【问题标题】:How this Fold Tree Function works in Haskell这个折叠树函数在 Haskell 中是如何工作的
【发布时间】:2019-03-12 17:29:47
【问题描述】:

在这里,我试图理解这个将树折叠为一个值的函数。它表明 foldTree 接受两个函数作为参数,它将第一个函数应用于 Tree a 的元素,然后将结果传递给第二个函数 (b->b->b) 再次执行一些操作并产生最终结果。

foldTree :: (a -> b) -> (b -> b -> b) -> Tree a -> b
foldTree f g (Leaf x) = f x
foldTree f g (Node tl tr) = g (foldTree f g tl) (foldTree f g tr) 

我正在尝试跟踪输入以查看它是如何工作的。

Input 1:  foldTree (*2) (\x y -> x + y) (Leaf 6)
Input 2:  foldTree (*2) (\x y -> x + y) (Node (Node (Leaf 1) (Leaf 2)) (Leaf 4))

返回

Output 1 : 12
Output 2 : 14

我在理解中面临的问题是第二个函数参数操作在哪里执行?以及它实际上如何将值传递给第二个函数,显然第二个函数将两个值作为参数,但第一个函数只返回一个值......从哪里传递第二个值?我可以说它需要第一个函数 twice 的结果,以便 xy 值相同吗?因为第二个函数(\x y -> x + y) 需要两个参数?但结果将与输出 1 和 2 中提到的不同。

其次,它是在执行第二个函数后返回最终结果,还是在仅应用第一个函数后返回结果,因为我很困惑,即使我删除了第二个函数,它也会产生相同的结果。

第三,g 在两个大括号之外的目的是什么? ***g*** (foldTree f g tl) (foldTree f g tr) 从一开始就将其作为数据构造函数还是什么?我知道数据构造函数可以构造为智能构造函数,但在这里它是如何处理的。

我很困惑理解这一点,可能我在这个中复杂化了很多概念吗?请不要犹豫,详细说明。

【问题讨论】:

  • foldTree f g tree 基本上将f 应用于树的每个叶子,然后在每个Node 的组件之间递归地应用g,例如foldTree f g (Node (Node (Leaf 1) (Leaf 2)) (Leaf 4)) = g (g (f 1) (f 2)) (f 4).
  • ... 或 IOW,(f 1 `g` f 2) `g` f 4 == ((*2) 1 + (*2) 2) + (*2) 4 == (1*2 + 2*2) + 4*2
  • @bradrn 谢谢,我明白你所说的,但我很困惑它如何解释将 g 应用于 Node.js 的组件。在这种情况下,g 的定义是什么?它是如何解释 (b->b->b) 函数的,而在我看来,它与函数 (a->b) 相同。抱歉,我是这方面的初学者。
  • @bradrn 如何将 (\x y -> x + y) 映射到 (b->b->b) 第一个函数将输出传递到 (\x y -> x 后 x 和 y 是什么+ y)

标签: haskell tree fold


【解决方案1】:

要了解foldTree f g tree 的结果,您可以使用以下技术:

  • 使用构造函数记下tree 的值,例如在您的示例中,我们有 (Node (Node (Leaf 1) (Leaf 2)) (Leaf 4))
  • 在语法上将Leaf 替换为f,将Node 替换为g。对于前面的例子,我们得到(g (g (f 1) (f 2)) (f 4))
  • 使用函数fg 的定义来计算最后一个表达式的结果。例如,我们得到((+) ((+) ((*2) 1) ((*2) 2)) ((*2) 4)),即 ((+) ((+) (1*2) (2*2)) (4*2))((1*2) + (2*2)) + (4*2)(2+4)+8 = 14

请注意我们如何将一元构造函数 Leaf 替换为一元函数 f,并将二元构造函数 Node 替换为二元函数 g。所以,我们的函数总是有正确数量的参数。更一般地说,类型匹配得很好。

【讨论】:

  • 感谢您的详细解答。它将 g 视为二进制数据构造函数?为什么我们用 Node 代替 g?而 Node 是 Tree 的一部分,而 as (b->b->b) 是一个单独的二元函数?
  • @Sniper g 在折叠时确实扮演了二进制构造函数Node 的角色。我们将Node 替换为g,因为foldTree 是这样定义的:foldTree f g (Node .. ..) = g (..) (..),所以Node 在扩展定义时变为g。本质上,Node 是一个二进制构造函数函数,采用两个Trees,而g 将其概括为采用任意两个bs。同样,Leaf ... 在扩展定义时变为f ..
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-03
  • 1970-01-01
相关资源
最近更新 更多