如果您有二叉树,则计算叶子的函数是例如:
> leaves ' :: (Tree a) -> [a]
> leaves ' b = lvl b []
> where lvl Nil as = as
> lvl (Leaf a) as = a:as
> lvl (Br l r) as = lvl l (lvl r as)
现在我必须对Multitrees(玫瑰树)做同样的事情。它应该以
开头multileaves :: MultiTree a - > [α]
我的第一个想法是
> data MultiTree a = Nil
> | Leaf a
> | Br [MultiTree a] deriving Show
> multileaves :: MultiTree a -> [a]
> multileaves b = lvl b []
> where lvl Nil as = as
> lvl (Leaf a) as = a:as
> lvl (Br a) as = Br a (map (multileaves (a:b) as)
但是Hugs说这可能是一个糟糕的布局。
我不堪重负。想法?
感谢。
答案 0 :(得分:4)
您必须将从lvl
开始的最后两行缩进到与上一行中lvl
相同的点
multileaves b = lvl b []
where lvl Nil as = as
lvl (Leaf a) as = a:as
lvl (Br a) as = Br a (map (multileaves (a:b) as)
或者您可以使用我喜欢的表格
multileaves b = lvl b []
where
lvl Nil as = as
lvl (Leaf a) as = a:as
lvl (Br a) as = Br a (map (multileaves (a:b) as)
修改强>
在仔细检查帖子中的文字后,看起来您正在使用标签进行缩进。由于空白不一致,这通常会导致Haskell出现问题,我建议切换到仅使用空格。除非您使用notepad.exe,否则您的编辑器应该有一个选项可以在按Tab键时插入空格。
答案 1 :(得分:3)
基本上有两件事需要确保,因此Haskell程序甚至会解析:
匹配括号。应该足够明显,但你的例子的最后一行有3个开放,只有2个关闭的parens。做到这一点
Br a (map (multileaves (a:b) as))
或(首选)
Br a . map $ multileaves (a:b) as
压痕。让我们忘记标签,这些是邪恶的 - 在你的编辑器/ IDE中关闭它们。 (任何正确的编辑器也应该使不匹配的括号明显,BTW!)
您需要确保的是where
或let
中的下一个本地绑定,do
块中的下一个语句,或case
选择中的下一个案例,尽可能多的空格缩进,因为第一个这样的语句左边有字符。在你的情况下,如果你有行
where lvl Nil as = as
然后下一个需要缩进,以便lvl
与前一个对齐,就像在原始leaves'
中一样。
一旦你的程序解析,你会发现其他问题:
b
您正在处理的整个树。你在每一个递归步骤中重新引用它,这显然让你处于无限循环中。我不知道为什么你认为你需要:
; a
显然已经是您Multitree
类型的列表。您只想映射该列表。
结果类型都错了。你需要一个列表,但你又在构建一个树。