module Data.Type.Dec (
Neg,
Dec (..),
Decidable (..),
toNegNeg,
tripleNeg,
contradict,
contraposition,
decNeg,
decShow,
decToMaybe,
decToBool,
) where
import Data.Void (Void)
type Neg a = a -> Void
data Dec a
= Yes a
| No (Neg a)
class Decidable a where
decide :: Dec a
toNegNeg :: a -> Neg (Neg a)
toNegNeg :: a -> Neg (Neg a)
toNegNeg x :: a
x = (Neg a -> Neg a
forall a b. (a -> b) -> a -> b
$ a
x)
tripleNeg :: Neg (Neg (Neg a)) -> Neg a
tripleNeg :: Neg (Neg (Neg a)) -> Neg a
tripleNeg f :: Neg (Neg (Neg a))
f a :: a
a = Neg (Neg (Neg a))
f (a -> Neg (Neg a)
forall a. a -> Neg (Neg a)
toNegNeg a
a)
contradict :: (a -> Neg b) -> b -> Neg a
contradict :: (a -> Neg b) -> b -> Neg a
contradict f :: a -> Neg b
f b :: b
b a :: a
a = a -> Neg b
f a
a b
b
contraposition :: (a -> b) -> Neg b -> Neg a
contraposition :: (a -> b) -> Neg b -> Neg a
contraposition f :: a -> b
f nb :: Neg b
nb a :: a
a = Neg b
nb (a -> b
f a
a)
instance Eq a => Eq (Dec a) where
Yes x :: a
x == :: Dec a -> Dec a -> Bool
== Yes y :: a
y = a
x a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
y
Yes _ == No _ = Bool
False
No _ == Yes _ = Bool
False
No _ == No _ = Bool
True
instance Ord a => Ord (Dec a) where
compare :: Dec a -> Dec a -> Ordering
compare (Yes a :: a
a) (Yes b :: a
b) = a -> a -> Ordering
forall a. Ord a => a -> a -> Ordering
compare a
a a
b
compare (No _) (Yes _) = Bool -> Bool -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Bool
False Bool
True
compare (Yes _) (No _) = Bool -> Bool -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Bool
True Bool
False
compare (No _) (No _) = Ordering
EQ
decNeg :: Dec a -> Dec (Neg a)
decNeg :: Dec a -> Dec (Neg a)
decNeg (Yes p :: a
p) = Neg (Neg a) -> Dec (Neg a)
forall a. Neg a -> Dec a
No (a -> Neg (Neg a)
forall a. a -> Neg (Neg a)
toNegNeg a
p)
decNeg (No np :: Neg a
np) = Neg a -> Dec (Neg a)
forall a. a -> Dec a
Yes Neg a
np
decShow :: Show a => Dec a -> String
decShow :: Dec a -> String
decShow (Yes x :: a
x) = "Yes " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> a -> String -> String
forall a. Show a => Int -> a -> String -> String
showsPrec 11 a
x ""
decShow (No _) = "No <toVoid>"
decToMaybe :: Dec a -> Maybe a
decToMaybe :: Dec a -> Maybe a
decToMaybe (Yes p :: a
p) = a -> Maybe a
forall a. a -> Maybe a
Just a
p
decToMaybe (No _) = Maybe a
forall a. Maybe a
Nothing
decToBool :: Dec a -> Bool
decToBool :: Dec a -> Bool
decToBool (Yes _) = Bool
True
decToBool (No _) = Bool
False