-
Notifications
You must be signed in to change notification settings - Fork 2
/
monads.hs
88 lines (65 loc) · 2.8 KB
/
monads.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
70
71
72
73
74
75
76
77
78
79
80
81
82
{-
5.2.1
Implement a Monad instance for the list constructor, []. Follow the types!
-}
instance Monad [] where
return' x = [x]
m >>= f = concat (map f m)
{-
5.2.2
Implement a Monad instance for ((->) e).
-}
instance Monad ((->) e) where
return = const
m >>= f = \e -> f (m e) e
{-
5.2.3
Implement Functor and Monad instances for Free f, defined as
data Free f a = Var a
| Node (f (Free f a))
You may assume that f has a Functor instance. This is known as the free monad built from the functor f.
-}
data Free f a = Var a | Node (f (Free f a))
instance (Functor f) => Functor (Free f) where
fmap g (Var x) = Var (g x)
fmap g (Node x) = Node (fmap (fmap g) x)
instance (Functor f) => Monad (Free f) where
return x = (Var x)
(Node m) >>= g = Node (fmap (>>=g) m)
{-
5.3.1
Implement (>>=) in terms of fmap (or liftM) and join.
-}
(>>=) :: (Applicative m) => m a -> (a -> m b) -> m b
m >>= f = join (fmap f m)
{-
5.3.2
Now implement join and fmap (liftM) in terms of (>>=) and return
-}
join :: (Monad m) => m (m a) -> m a
join m = m >>= id
fmap :: (Monad m) => (a -> b) -> m a -> m b
fmap f m = m >>= (return . f)
{-
5.5.1
Given the definition g >=> h = \x -> g x >>= h, prove the equivalence of the above laws and the usual monad laws.
With help from http://mvanier.livejournal.com/4586.html
-}
-- Assuming the >=> laws we derive using the definition of >=>:
return >==> g = g -- implies that, using the definition of >=>
(\x -> return x) >>= g = \x -> g x -- which implies
return x >>= g = g -- which proves the first monad law. Note that since implications go
-- in the other direction as well that the monad laws imply the laws for >=>
-- For the second monad law we use a similar derivation, beginning with the second >=> law
g >=> return = g -- implies that, using the definition of >=>
(\x -> g x) >>= return = \x -> g x -- and letting g x = m, this implies that
m >>= return = m -- which proves the second monad law. Again, implications go in the other
-- other direction as well, showing that the monad laws imply the >=> laws.
-- We now prove the associativity of the third law.
-- Assuming the associativity law for >=>, we then transform into monadic bind by basically using the definition of >==> on both sides of the equals and reducing >=> to >>=.
(f >=> g) >=> h = f >=> (g >=> h)
\x -> ((f >=> g) x >>= h) = \x -> (f x >>= (g >=> h))
(f >=> g) x >>= h = f x >>= (g >=> h)
(\y -> (f y >>= g)) x >>= h = f x >>= (\y -> g y >>= h) -- letting m = f x
(f x >>= g) >>= h = m >>= (\y -> g y >>= h)
(m >>= g) >>= h = m >>= (\y -> g y >>= h)