【发布时间】:2013-04-26 01:29:23
【问题描述】:
data Tree a = Tree a [Tree a]
请注意,我们不允许空树,叶子是具有空子树列表的树。
treeFold :: (a -> [b] -> b) -> Tree a -> b
treeFold f (Tree x s) = f x (map (treeFold f) s)
鉴于以上信息,我不明白树折叠功能如何 通过递归地对子树应用折叠操作来返回结果,然后将函数应用于根处的标签以及从子树返回的结果。
我也不明白 tree Fold 函数如何只接受一个参数而不是 2 个,当它作为参数传递给 map 函数并且它仍然可以正常编译和运行时。
例如下面的树大小函数,对树的节点进行计数。
treeSize :: Tree a -> Int
treeSize = treeFold (\x ys -> 1 + sum ys)
所以运行 treeSize tree 其中tree = Tree 4 [Tree 1 [Tree 2 [], Tree 3 []]] 将树的大小设为 4。
在上面的树大小函数中,树折叠函数也传递了一个参数而不是两个。此外,传递给树折叠函数的 x 并没有在任何地方使用,所以你为什么需要它。删除它会导致程序无法编译,并给出以下错误消息。
Couldn't match type `a' with `[[Int] -> Int]'
`a' is a rigid type variable bound by
the type signature for treeSize :: Tree a -> Int
at treeFold.hs:15:1
In the first argument of `sum', namely `ys'
In the second argument of `(+)', namely `sum ys'
In the expression: 1 + sum ys
任何帮助将不胜感激。
【问题讨论】: