-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathNatEncoded.hs
69 lines (52 loc) · 1.32 KB
/
NatEncoded.hs
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
module NatEncoded
(
Nat
, uu, vv, phi, psi
) where
data Nat =
Nat Integer
| Gauche Nat
| Droit Nat
| Pair Nat Nat
deriving (Eq, Ord)
-- "Ord Nat" is only for "Data.Map.Map Nat x"
instance Show Nat where
showsPrec d (Nat n) = showsPrec d n
showsPrec d (Gauche n) =
showString "g" . showsPrec 11 n
showsPrec d (Droit n) =
showString "d" . showsPrec 11 n
showsPrec d (Pair n m) =
showChar '<' .
shows n .
showChar ',' .
shows m .
showChar '>'
instance Num Nat where
fromInteger n
| n >= 0 = Nat n
| otherwise = error "fromInteger Nat: negative"
(Nat n) + (Nat m) = Nat (n + m)
_ + _ = error "(+) Nat: encoded"
(Nat n) * (Nat m) = Nat (n * m)
_ * _ = error "(*) Nat: encoded"
abs = id
signum (Nat 0) = (Nat 0)
signum (Nat _) = (Nat 1)
signum _ = error "signum Nat: encoded"
(Nat n) - (Nat m) = let k = n - m in if k >= 0
then Nat k
else error "(-) Nat: negative"
_ - _ = error "(-) Nat: encoded"
uu :: (Nat, Nat) -> Nat
uu (n, m) = Pair n m
vv :: Nat -> (Nat, Nat)
vv (Pair n m) = (n, m)
vv x = error $ "vv: input = " ++ show x
phi :: Either Nat Nat -> Nat
phi (Left n) = Gauche n
phi (Right n) = Droit n
psi :: Nat -> Either Nat Nat
psi (Gauche n) = Left n
psi (Droit n) = Right n
psi x = error $ "psi: input = " ++ show x