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