1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
|
{-# LANGUAGE CPP #-}
#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 702
{-# LANGUAGE Trustworthy #-}
#endif
#ifdef LANGUAGE_DeriveDataTypeable
{-# LANGUAGE DeriveDataTypeable #-}
#endif
#ifdef LANGUAGE_DeriveGeneric
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE StandaloneDeriving #-}
#endif
#ifndef MIN_VERSION_base
#define MIN_VERSION_base(x,y,z) 1
#endif
#ifndef MIN_VERSION_semigroups
#define MIN_VERSION_semigroups(x,y,z) 1
#endif
-----------------------------------------------------------------------------
-- |
-- Copyright : (C) 2008-2015 Edward Kmett
-- License : BSD-style (see the file LICENSE)
--
-- Maintainer : Edward Kmett <ekmett@gmail.com>
-- Stability : provisional
-- Portability : portable
--
----------------------------------------------------------------------------
module Data.Void
( Void
, absurd
, vacuous
, vacuousM
) where
import Control.DeepSeq (NFData(..))
import Control.Monad (liftM)
import Data.Ix
import Data.Hashable
import Data.Semigroup (Semigroup(..))
#ifdef LANGUAGE_DeriveDataTypeable
import Data.Data
#endif
#ifdef LANGUAGE_DeriveGeneric
import GHC.Generics
#endif
#if MIN_VERSION_base(4,0,0)
import Control.Exception
#endif
import Language.Haskell.TH.Syntax (Lift (..))
-- | A logically uninhabited data type.
#if __GLASGOW_HASKELL__ < 700
data Void = Void !Void
#else
newtype Void = Void Void
#endif
#ifdef LANGUAGE_DeriveDataTypeable
deriving (Data, Typeable)
#endif
#ifdef LANGUAGE_DeriveGeneric
deriving instance Generic Void
#endif
instance Eq Void where
_ == _ = True
instance Hashable Void where
hashWithSalt _ = absurd
instance Ord Void where
compare _ _ = EQ
instance Show Void where
showsPrec _ = absurd
-- | Reading a 'Void' value is always a parse error, considering 'Void' as
-- a data type with no constructors.
instance Read Void where
readsPrec _ _ = []
-- | Since 'Void' values logically don't exist, this witnesses the logical
-- reasoning tool of \"ex falso quodlibet\".
absurd :: Void -> a
absurd a = a `seq` spin a where
spin (Void b) = spin b
-- | If 'Void' is uninhabited then any 'Functor' that holds only values of type 'Void'
-- is holding no values.
vacuous :: Functor f => f Void -> f a
vacuous = fmap absurd
-- | If 'Void' is uninhabited then any 'Monad' that holds values of type 'Void'
-- is holding no values.
vacuousM :: Monad m => m Void -> m a
vacuousM = liftM absurd
instance Semigroup Void where
a <> _ = a
#if MIN_VERSION_semigroups(0,17,0)
stimes _ a = a
#else
times1p _ a = a
#endif
instance Ix Void where
range _ = []
index _ = absurd
inRange _ = absurd
rangeSize _ = 0
#if MIN_VERSION_base(4,0,0)
instance Exception Void
#endif
-- | Defined as @'rnf' = 'absurd'@.
instance NFData Void where
rnf = absurd
instance Lift Void where
lift = return . absurd
|