{-# LANGUAGE Safe #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Data.Type.Dec (
Neg,
Dec (..),
Decidable (..),
toNegNeg,
tripleNeg,
contradict,
contraposition,
decNeg,
decShow,
decToMaybe,
decToBool,
boringYes,
absurdNo,
) where
import Data.Void (Void)
import Data.Boring (Absurd (..), Boring (..))
type Neg a = a -> Void
data Dec a
= Yes a
| No (Neg a)
class Decidable a where
decide :: Dec a
instance Decidable () where
decide :: Dec ()
decide = forall a. a -> Dec a
Yes ()
instance Decidable Void where
decide :: Dec Void
decide = forall a. Neg a -> Dec a
No forall a. a -> a
id
instance (Decidable a, Decidable b) => Decidable (a, b) where
decide :: Dec (a, b)
decide = case forall a. Decidable a => Dec a
decide :: Dec a of
No Neg a
nx -> forall a. Neg a -> Dec a
No (\(a, b)
c -> Neg a
nx (forall a b. (a, b) -> a
fst (a, b)
c))
Yes a
x -> case forall a. Decidable a => Dec a
decide :: Dec b of
No Neg b
ny -> forall a. Neg a -> Dec a
No (\(a, b)
c -> Neg b
ny (forall a b. (a, b) -> b
snd (a, b)
c))
Yes b
y -> forall a. a -> Dec a
Yes (a
x, b
y)
toNegNeg :: a -> Neg (Neg a)
toNegNeg :: forall a. a -> Neg (Neg a)
toNegNeg a
x = (forall a b. (a -> b) -> a -> b
$ a
x)
tripleNeg :: Neg (Neg (Neg a)) -> Neg a
tripleNeg :: forall a. Neg (Neg (Neg a)) -> Neg a
tripleNeg Neg (Neg (Neg a))
f a
a = Neg (Neg (Neg a))
f (forall a. a -> Neg (Neg a)
toNegNeg a
a)
contradict :: (a -> Neg b) -> b -> Neg a
contradict :: forall a b. (a -> Neg b) -> b -> Neg a
contradict a -> Neg b
f b
b a
a = a -> Neg b
f a
a b
b
contraposition :: (a -> b) -> Neg b -> Neg a
contraposition :: forall a b. (a -> b) -> Neg b -> Neg a
contraposition a -> b
f Neg b
nb a
a = Neg b
nb (a -> b
f a
a)
instance Eq a => Eq (Dec a) where
Yes a
x == :: Dec a -> Dec a -> Bool
== Yes a
y = a
x forall a. Eq a => a -> a -> Bool
== a
y
Yes a
_ == No Neg a
_ = Bool
False
No Neg a
_ == Yes a
_ = Bool
False
No Neg a
_ == No Neg a
_ = Bool
True
instance Ord a => Ord (Dec a) where
compare :: Dec a -> Dec a -> Ordering
compare (Yes a
a) (Yes a
b) = forall a. Ord a => a -> a -> Ordering
compare a
a a
b
compare (No Neg a
_) (Yes a
_) = forall a. Ord a => a -> a -> Ordering
compare Bool
False Bool
True
compare (Yes a
_) (No Neg a
_) = forall a. Ord a => a -> a -> Ordering
compare Bool
True Bool
False
compare (No Neg a
_) (No Neg a
_) = Ordering
EQ
decNeg :: Dec a -> Dec (Neg a)
decNeg :: forall a. Dec a -> Dec (Neg a)
decNeg (Yes a
p) = forall a. Neg a -> Dec a
No (forall a. a -> Neg (Neg a)
toNegNeg a
p)
decNeg (No Neg a
np) = forall a. a -> Dec a
Yes Neg a
np
decShow :: Show a => Dec a -> String
decShow :: forall a. Show a => Dec a -> String
decShow (Yes a
x) = String
"Yes " forall a. [a] -> [a] -> [a]
++ forall a. Show a => Int -> a -> ShowS
showsPrec Int
11 a
x String
""
decShow (No Neg a
_) = String
"No <toVoid>"
decToMaybe :: Dec a -> Maybe a
decToMaybe :: forall a. Dec a -> Maybe a
decToMaybe (Yes a
p) = forall a. a -> Maybe a
Just a
p
decToMaybe (No Neg a
_) = forall a. Maybe a
Nothing
decToBool :: Dec a -> Bool
decToBool :: forall a. Dec a -> Bool
decToBool (Yes a
_) = Bool
True
decToBool (No Neg a
_) = Bool
False
instance Decidable a => Boring (Dec a) where
boring :: Dec a
boring = forall a. Decidable a => Dec a
decide
boringYes :: Boring a => Dec a
boringYes :: forall a. Boring a => Dec a
boringYes = forall a. a -> Dec a
Yes forall a. Boring a => a
boring
absurdNo :: Absurd a => Dec a
absurdNo :: forall a. Absurd a => Dec a
absurdNo = forall a. Neg a -> Dec a
No forall a b. Absurd a => a -> b
absurd