MultiTree计算叶子(Haskell)

时间:2014-01-14 14:46:00

标签: haskell

如果您有二叉树,则计算叶子的函数是例如:

> 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说这可能是一个糟糕的布局。

我不堪重负。想法?

感谢。

2 个答案:

答案 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!)
    您需要确保的是wherelet中的下一个本地绑定,do块中的下一个语句,或case选择中的下一个案例,尽可能多的空格缩进,因为第一个这样的语句左边有字符。在你的情况下,如果你有行

         where lvl Nil as = as
    

    然后下一个需要缩进,以便lvl与前一个对齐,就像在原始leaves'中一样。

一旦你的程序解析,你会发现其他问题:

  • b 您正在处理的整个树。你在每一个递归步骤中重新引用它,这显然让你处于无限循环中。我不知道为什么你认为你需要:; a显然已经是您Multitree类型的列表。您只想映射该列表。

  • 结果类型都错了。你需要一个列表,但你又在构建一个树。