-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathPeano.hs
55 lines (37 loc) · 1.42 KB
/
Peano.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
{-# LANGUAGE FlexibleInstances #-}
import Prelude
data Church' x = Church' ((x -> x) -> x -> x)
-- Sepearate the type parameter in positive and negative occurences
data Church x y = Church ((x -> x) -> x -> y)
runChurch :: Church x y -> (x -> x) -> (x -> y)
runChurch (Church g) f = g f
zero :: Church x x
zero = Church (\_ x -> x)
one :: Church x x
one = Church (\f x -> f x)
suc :: Church x x -> Church x x
suc (Church n) = Church (\f x -> f (n f x))
plus :: Church x x -> Church x x -> Church x x
plus (Church n) (Church m) = Church (\f x -> n f (m f x))
mult :: Church x x -> Church x x -> Church x x
mult (Church n) (Church m) = Church (\f x -> m (n f) x)
instance Num (Church x x) where
fromInteger 0 = zero
fromInteger n = suc (fromInteger (n - 1))
(+) = plus
(*) = mult
(-) = error "(-) is not defined for church numbers"
abs = error "abs is not defined for church numners"
signum = error "signum is not defined for church numbers"
nice :: Church x x
nice = 3
instance Functor (Church x) where
fmap h (Church g) = Church (\f x -> h (g f x))
instance Applicative (Church x) where
pure y = Church (\f x -> y)
(Church g) <*> (Church y) = Church (\f x -> (g f x) (y f x))
joinChurch :: Church x (Church x y) -> Church x y
joinChurch g = Church (\f x -> runChurch ((runChurch g) f x) f x)
instance Monad (Church x) where
return = pure
m >>= k = joinChurch ((pure k) <*> m)