树折操作?

Pha*_*rus 8 tree haskell fold

我正在Haskell中学习一个类,我们需要为以下定义的树定义折叠操作:

data Tree a = Lf a | Br (Tree a) (Tree a)
Run Code Online (Sandbox Code Playgroud)

我似乎无法找到关于"tfold"操作的任何信息,或者它真的应该做什么.任何帮助将不胜感激.

yat*_*975 11

我总是认为折叠是一种通过其他函数系统地替换构造函数的方法.因此,例如,如果您有自己动手的List类型(定义为data List a = Nil | Cons a (List a)),则相应的折叠可以写为:

listfold nil cons Nil = nil
listfold nil cons (Cons a b) = cons a (listfold nil cons b)
Run Code Online (Sandbox Code Playgroud)

或者,可能更简洁,如:

listfold nil cons = go where
    go Nil = nil
    go (Cons a b) = cons a (go b)
Run Code Online (Sandbox Code Playgroud)

类型listfoldb -> (a -> b -> b) -> List a -> b.也就是说,需要两个"替代建设者"; 一个告诉如何将Nil值转换为b构造函数的另一个替换构造Cons函数,告诉Cons构造函数(类型a)的第一个值应该如何与类型值组合b(为什么b?因为折叠已经递归应用了! )产生一个新的b,最后一个List a应用整个she-bang - 结果b.

在你的情况下,类型tfold应该是(a -> b) -> (b -> b -> b) -> Tree a -> b类似的推理; 希望你能从那里拿走它!

  • 这是完全正确的.但是,我认为将这一点添加到你的答案是有用的:如果`tfold`被正确定义,那么`tfold Lf Br`应该是`Tree a`上的标识函数 - 一个采用树并返回相同树的函数.(同样对于你的例子,`listfold Nil Cons`是`List`的标识.) (6认同)

ami*_*dfv 1

列表上的折叠是将列表缩减为单个元素。它采用一个函数,然后将该函数应用于元素,一次两个,直到只有一个元素。例如:

Prelude> foldl1 (+) [3,5,6,7]
21
Run Code Online (Sandbox Code Playgroud)

...通过一一运算找到:

3 + 5 == 8
8 + 6 == 14
14 + 7 == 21
Run Code Online (Sandbox Code Playgroud)

可以写一个折叠

ourFold :: (a -> a -> a) -> [a] -> a
ourFold _         [a]        = a -- pattern-match for a single-element list. Our work is done.
ourFold aFunction (x0:x1:xs) = ourFold aFunction ((aFunction x0 x1):xs)
Run Code Online (Sandbox Code Playgroud)

树折叠可以做到这一点,但会沿着树枝向上或向下移动。为此,它首先需要进行模式匹配以查看您是在叶子还是分支上进行操作。

treeFold _ (Lf a)   = Lf a -- You can't do much to a one-leaf tree
treeFold f (Br a b) = -- ...
Run Code Online (Sandbox Code Playgroud)

剩下的就交给你了,因为这是家庭作业。如果您遇到困难,请首先尝试考虑类型应该是什么。