The document discusses representing datatypes recursively and modularly using functors and fixed points. It introduces signature functors that define the structure of datatypes, and shows how to combine functors using coproducts. It then presents folds as a way to interpret recursive datatypes by structural recursion. Finally, it defines evaluation algebras that provide the semantics for folding, allowing recursive values to be evaluated in a monadic context.
4. flatten a recursive
datatype:
data Term = Val Int | Add Term Term
| Throw | Catch Term Term
5. flatten a recursive
datatype:
data Term = Val Int | Add Term Term
| Throw | Catch Term Term
| If Bool Term Term
6. flatten a recursive
datatype:
data Term = Val Int | Add Term Term
| Throw | Catch Term Term
data Arith e = Val Int | Add e e
data Except e = Throw | Catch e e the Menu
7. flatten a recursive
datatype:
data Term = Val Int | Add Term Term
| Throw | Catch Term Term
| If Bool Term Term
data Arith e = Val Int | Add e e
data Except e = Throw | Catch e e the Menu
data Branch e = If Bool e e
8. signature functor:
data Arith e = Val Int | Add e e
data Except e = Throw | Catch e e
instance Functor Except where
fmap f Throw = Throw
fmap f (Catch x g) = Catch (f x) (f g)
instance Functor Arith where
fmap f (Val n) = Val n
fmap f (Add x y) = Add (f x) (f y)
9. the “recursive”:
(Fix F = F(Fix F
) )
data Fix f = In (f (Fix f))
10. the “recursive”:
(Fix F = F(Fix F
) )
data Fix f = In (f (Fix f))
example :
(In $ Val 2) :: Fix Arith
11. the “recursive”:
(Fix F = F(Fix F
) )
data Fix f = In (f (Fix f))
example :
In $ (Add (In $ Val 1) (In $ Val 2)) :: Fix Arith
12. the “recursive”:
(Fix F = F(Fix F
) )
data Fix f = In (f (Fix f))
example :
In $ Add (In $ Throw) (In $ Val 2) :: ???
13. the “recursive”:
(Fix F = F(Fix F
) )
data Fix f = In (f (Fix f))
example :
In $ Add (In $ Throw) (In $ Val 2) :: ???
Couldn't match expected type `Arith' with actual type `Except'
14. combining functor by
coproduct:
C
f g data (f :+: g) e = Inl (f e)
| Inr (f e)
A [f, g] B
instance (Functor f, Functor g)
=> Functor (f :+: g) where
inl inr fmap h (Inl x) = Inl (fmap h x)
fmap h (Inr y) = Inr (fmap h y)
A+B
15. combining functor by
coproduct:
• In $ Val 2 :: Fix Arith
• In $ Inl $ Val 2 :: Fix (Arith :+: g)
• In $ Add (In $ Throw) (In $ Val 2) :: ???
• In $ Inl $ Add
(In $ Inr $ Throw)
(In $ Inl $ Val 2) :: Fix (Arith :+: Except)
16. combining functor by
coproduct:
• In $ Val 2 :: Fix Arith
• In $ Inl $ Val 2 :: Fix (Arith :+: g)
• In $ Add (In $ Throw) (In $ Val 2) :: ???
• In $ Inl $ Add
(In $ Inr $ Throw)
(In $ Inl $ Val 2) :: Fix (Arith :+: Except)
17. combining functor by
coproduct:
• In $ Val 2 :: Fix Arith
• In $ Inl $ Val 2 :: Fix (Arith :+: g)
• In $ Add (In $ Throw) (In $ Val 2) :: ???
• In $ Inl $ Add
(In $ Inr $ Throw)
(In $ Inl $ Val 2) :: Fix (Arith :+: Except)
19. why fold
• A recursive datatype, (Fix f), represents a
expression language.
• the semantics of such expression language
has type: Fix f → m Value
• we need fold for type Fix
21. fold for type Fix
a
(Fix F) F(Fix F)
([ f ]) F([ f ])
m Value F(m Value)
f
22. fold for type Fix
(pattern match)
(Fix F) F(Fix F)
fold f fmap (fold f )
m Value F(m Value)
f
23. fold for type Fix
(pattern match)
(Fix F) F(Fix F)
fold f fmap (fold f )
m Value F(m Value)
f
fold f = ...
24. fold for type Fix
(pattern match)
(Fix F) F(Fix F)
fold f fmap (fold f )
m Value F(m Value)
f
fold f = (In t) → t
25. fold for type Fix
(pattern match)
(Fix F) F(Fix F)
fold f fmap (fold f )
m Value F(m Value)
f
fold f = (In t) → fmap (fold f) $ t
26. fold for type Fix
(pattern match)
(Fix F) F(Fix F)
fold f fmap (fold f )
m Value F(m Value)
f
fold f = (In t) → f $ fmap (fold f) $ t
27. evaluation-algebra
• fold :: Functor f => (f a → a) → Fix f → a
• fold f = (In t) → f (fmap (fold f) t)
• we need a (f a → a) as a parameter
• f-algebra
• evaluation-algebra
28. evaluation-algebra
eval-alge
m Value F(m Value)
class (Monad m, Functor f) => EvalAlge f m where
evalAlge :: f (m Value) →(m Value)
29. evaluation-algebra
instance Monad m => EvalAlge Arith m where
evalAlge (Val n) = return n
evalAlge (Add x y) = x >>= m ->
y >>= n ->
return (m+n)
34. evaluation
• fold :: Functor f => (f a → a) → Fix f → a
• evalAlge :: f (m Value) →(m Value)
• eval :: (Functor f, Monad m) => Fix f → m Value
• eval = fold evalAlg
• here, f can be Arith, Except or (Arith :+: Except)