Implement the EmptyDataDeriving proposal
[ghc.git] / libraries / base / Data / Void.hs
1 {-# LANGUAGE DeriveDataTypeable #-}
2 {-# LANGUAGE DeriveGeneric #-}
3 {-# LANGUAGE EmptyCase #-}
4 {-# LANGUAGE EmptyDataDeriving #-}
5 {-# LANGUAGE Safe #-}
6 {-# LANGUAGE StandaloneDeriving #-}
7
8 -----------------------------------------------------------------------------
9 -- |
10 -- Copyright : (C) 2008-2014 Edward Kmett
11 -- License : BSD-style (see the file libraries/base/LICENSE)
12 --
13 -- Maintainer : Edward Kmett <ekmett@gmail.com>
14 -- Stability : provisional
15 -- Portability : portable
16 --
17 -- A logically uninhabited data type, used to indicate that a given
18 -- term should not exist.
19 --
20 -- @since 4.8.0.0
21 ----------------------------------------------------------------------------
22 module Data.Void
23 ( Void
24 , absurd
25 , vacuous
26 ) where
27
28 import Control.Exception
29 import Data.Data
30 import Data.Ix
31 import GHC.Generics
32 import Data.Semigroup (Semigroup(..), stimesIdempotent)
33
34 -- | Uninhabited data type
35 --
36 -- @since 4.8.0.0
37 data Void deriving
38 ( Eq -- ^ @since 4.8.0.0
39 , Data -- ^ @since 4.8.0.0
40 , Generic -- ^ @since 4.8.0.0
41 , Ord -- ^ @since 4.8.0.0
42 , Read -- ^ Reading a 'Void' value is always a parse error, considering
43 -- 'Void' as a data type with no constructors.
44 --
45 -- @since 4.8.0.0
46 , Show -- ^ @since 4.8.0.0
47 )
48
49 -- | @since 4.8.0.0
50 instance Ix Void where
51 range _ = []
52 index _ = absurd
53 inRange _ = absurd
54 rangeSize _ = 0
55
56 -- | @since 4.8.0.0
57 instance Exception Void
58
59 -- | @since 4.9.0.0
60 instance Semigroup Void where
61 a <> _ = a
62 stimes = stimesIdempotent
63
64 -- | Since 'Void' values logically don't exist, this witnesses the
65 -- logical reasoning tool of \"ex falso quodlibet\".
66 --
67 -- >>> let x :: Either Void Int; x = Right 5
68 -- >>> :{
69 -- case x of
70 -- Right r -> r
71 -- Left l -> absurd l
72 -- :}
73 -- 5
74 --
75 -- @since 4.8.0.0
76 absurd :: Void -> a
77 absurd a = case a of {}
78
79 -- | If 'Void' is uninhabited then any 'Functor' that holds only
80 -- values of type 'Void' is holding no values.
81 --
82 -- @since 4.8.0.0
83 vacuous :: Functor f => f Void -> f a
84 vacuous = fmap absurd