Haskell 目录类型

标签 haskell catamorphism recursion-schemes

阅读(并实现)http://blog.sumtypeofway.com/recursion-schemes-part-2/ 的一部分之后我仍然想知道 cata 函数中的类型是如何工作的。 cata 函数定义为:

mystery :: Functor f => (f a -> a) -> Term f -> a
mystery f = f . fmap (mystery f) . unTerm

我有类似 Term Expr 的东西。解包后我得到 Expr (Term Expr)。代数 (f) 的定义例如作为 f::Expr Int -> Int。我知道我可以轻松调用以下内容:

x = Literal "literal" :: Expr a
f :: Expr Int -> Int
f x :: Int

我也可以想象:

x = Literal "literal" :: Expr (Term Expr)
f :: Expr a -> Int
f x :: Int

但我认为以下内容不起作用:

x = Literal "literal" :: Expr (Term Expr)
f :: Expr Int -> Int
f x :: ???

但是,我仍然不明白它在 cata 函数中是如何工作的——我如何从 Expr (Term Expr)Expr a。我知道这些值确实有效,但我只是不明白类型 - 树叶中会发生什么?这确实是一个...

编辑:我会尝试更清楚地说明我不明白的地方。

在心理上,cata 似乎是这样工作的:

  • fmap f 应用于叶子。
  • 现在我有了 Expr Int,我可以调用 fmap f 到我拥有的节点并向上移动。

当我应用 fmap (cata f) 时,它显然不会以这种方式工作。然而,函数 f 最终以 Expr Int 作为参数(在叶子中)被调用。这种类型是如何从它之前的 Expr (Term Expr) 产生的?

最佳答案

这就是 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诠释。这是一个简单的转换,因为 Literal n::Expr a 用于任何 a

关于Haskell 目录类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33670665/

相关文章:

list - 列表列表中的最短列表(Haskell)

haskell - 自然数的初代数

scala - "coalgebra"在编程上下文中是什么意思?

haskell - 使用递归方案的核心递归斐波那契

haskell - 如何比较递归数据结构?

haskell - zipWith 用于 Haskell 中的树

haskell - 如何在 Haskell Turtle 库中将 `Shell Line` 转换为 `Text`?

scala - Scala 中 Catamorphisms 的高效实现

c# - 什么是变形,它在 C# 中是什么样子的?

haskell - 递归方案允许递归调用之间的依赖关系(有序变形?)