Skip to content

Commit 144efaf

Browse files
committed
Add State Monad examples for chapter 12
1 parent 17d1177 commit 144efaf

File tree

1 file changed

+64
-0
lines changed

1 file changed

+64
-0
lines changed

12-monads-and-more/12.03-monads.hs

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
type State = Int
2+
3+
newtype ST a = S (State -> (a, State))
4+
5+
apState :: ST a -> State -> (a, State)
6+
apState (S st) x = st x
7+
8+
mkState :: a -> ST a
9+
mkState x = S (\y -> (x, y))
10+
11+
instance Functor ST where
12+
fmap f (S st) = S $ \s ->
13+
let (x, s') = st s
14+
in (f x, s')
15+
16+
instance Applicative ST where
17+
pure x = S $ \s -> (x, s)
18+
(S fx) <*> (S gx) = S $ \s ->
19+
let (f, s') = fx s
20+
(x, s'') = gx s'
21+
in (f x, s'')
22+
23+
instance Monad ST where
24+
(S st) >>= f = S $ \s ->
25+
let (x, s') = st s
26+
(S st') = f x
27+
in st' s'
28+
29+
data Tree a = Leaf a
30+
| Node (Tree a) (Tree a)
31+
deriving Show
32+
33+
tree :: Tree Char
34+
tree = Node (Node (Leaf 'a') (Leaf 'b')) (Leaf 'c')
35+
36+
rlabel :: Tree a -> Int -> (Tree Int, Int)
37+
rlabel (Leaf _) n = (Leaf n, n + 1)
38+
rlabel (Node l r) n = (Node l' r', n'')
39+
where
40+
(l', n') = rlabel l n
41+
(r', n'') = rlabel r n'
42+
43+
fresh :: ST Int
44+
fresh = S (\n -> (n, n + 1))
45+
46+
alabel :: Tree a -> ST (Tree Int)
47+
alabel (Leaf _) = Leaf <$> fresh
48+
alabel (Node l r) = Node <$> alabel l <*> alabel r
49+
50+
mlabel :: Tree a -> ST (Tree Int)
51+
mlabel (Leaf _) = do n <- fresh
52+
return (Leaf n)
53+
mlabel (Node l r) = do l' <- mlabel l
54+
r' <- mlabel r
55+
return (Node l' r')
56+
57+
mlabel' :: Tree a -> ST (Tree Int)
58+
mlabel' (Leaf _) = fresh >>= \n ->
59+
return (Leaf n)
60+
mlabel' (Node l r) = mlabel' l >>= \l' ->
61+
mlabel' r >>= \r' ->
62+
return (Node l' r')
63+
64+

0 commit comments

Comments
 (0)