Haskell cata types

时间:2015-11-12 11:43:08

标签: haskell catamorphism recursion-schemes

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:

  • Apply fmap f to leaves.
  • Now I have 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?

1 个答案:

答案 0 :(得分:1)

这就是cata对树叶的操作方式。

假设f :: Expr Int -> Int。然后:

cata f :: Term Expr -> Int
fmap (cata f) :: Expr (Term Expr) -> Expr Int

现在,对于任何函数g :: a -> b,我们都有

fmap g :: Expr a -> Expr b
fmap g (Literal n) = Literal n
...

因此,在文字上,g并不重要。这意味着,选择a ~ Term Exprb ~ Intg = cata f我们有

fmap (cata f) (Literal n) = Literal n  :: Term Int
f (fmap (cata f) (Literal n)) = f (Literal n) :: Int

因此,粗略地说,在离开fmap (cata f)上是一个无操作,但它会将类型从Expr (Term Expr)更改为Expr Int。对于任何Literal n :: Expr a a,这是一个微不足道的转变。