在这里,我试图理解此功能,它将一棵树折叠为一个值。它显示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
我要理解的问题是在哪里执行第二个函数参数操作?以及它实际上如何将值传递给第二个函数,显然第二个函数将两个值作为参数,但第一个函数仅返回一个值...从第二个值传递的地方开始?我可以说它是第一个函数两次的结果,所以x
和y
的值是相同的吗?因为第二个函数(\x y -> x + y)
接受两个参数?但是结果将与输出1和2中提到的结果不同。
其次,它执行第二个功能后返回最终结果,或者仅应用第一个功能后返回结果,因为我很困惑,即使我删除了第二个功能,它也会产生相同的结果。
第三,g
在两个花括号之外的用途是什么? ***g*** (foldTree f g tl) (foldTree f g tr)
从一开始就将其视为数据构造函数还是什么?我知道数据构造函数可以构造为智能构造函数,但是在这里它是如何处理的。
我对此感到很困惑,这可能会使我复杂化很多概念吗?请不要犹豫,进入细节。
答案 0 :(得分:3)
要了解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))
。f
和g
的定义来计算最后一个表达式的结果。例如,我们得到((+) ((+) ((*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
。因此,对于我们的函数,我们总是有正确数量的参数。一般而言,类型会很好匹配。