After reading (and implementing) part of http://blog.sumtypeofway.com/recursion-schemes-part-2/ I still wonder how the types in the cata function work. The cata function is defined as:
mystery :: Functor f => (f a -> a) -> Term f -> a
mystery f = f . fmap (mystery f) . unTerm
I have something like Term Expr. After unpacking I get Expr (Term Expr). The algebra (f) is defined e.g. as f :: Expr Int -> Int. I know I could call the following easily:
x = Literal "literal" :: Expr a
f :: Expr Int -> Int
f x :: Int
I can also imagine:
x = Literal "literal" :: Expr (Term Expr)
f :: Expr a -> Int
f x :: Int
But the following I suppose wouldn't work:
x = Literal "literal" :: Expr (Term Expr)
f :: Expr Int -> Int
f x :: ???
However, I still don't get how it works in the cata function - how do I get from Expr (Term Expr) to Expr a. I understand that the values do work, but I just don't get the types - what happens in the leaves of the tree? This is indeed a mystery...
Edit: I'll try to state more clearly what I don't understand.
Mentally, the cata seems to work this way:
fmap f to leaves. Expr Int and I can call fmap f to the node I have and get way up.It doesn't obviously work this way as I am applying fmap (cata f). However, ultimately the function f gets called with Expr Int as an argument (in the leaves). How was this type produced from Expr (Term Expr) that it was before?
This is how cata operates on leaves.
Assume f :: Expr Int -> Int. Then:
cata f :: Term Expr -> Int
fmap (cata f) :: Expr (Term Expr) -> Expr Int
Now, for any function g :: a -> b, we have
fmap g :: Expr a -> Expr b
fmap g (Literal n) = Literal n
...
So, on literals, g is immaterial. This means that, choosing a ~ Term Expr, b ~ Int and g = cata f we have
fmap (cata f) (Literal n) = Literal n :: Term Int
f (fmap (cata f) (Literal n)) = f (Literal n) :: Int
So, roughly, on leaves fmap (cata f) is a no-op, but it changes the type from Expr (Term Expr) to Expr Int. This is a trivial transformation since Literal n :: Expr a for any a.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With