【问题标题】:Haskell Pre-order Traversal Tree to ListHaskell 预排序遍历树列表
【发布时间】:2014-10-07 04:59:09
【问题描述】:

我无法让我的代码对树进行预排序遍历到列表才能工作。树的定义如下:

data Tree a b = Branch b (Tree a b) (Tree a b)
          | Leaf a

我对前序遍历的定义如下:

preorder  :: (a -> c) -> (b -> c) -> Tree a b -> [c]
preorder f g (Leaf b) = [g b]
preorder f g (Branch a left right) = [f a] ++ preorder f g left ++ preorder f g right

但是我得到的错误是:

Couldn't match type `b' with `a'
  `b' is a rigid type variable bound by
      the type signature for
        preorder :: (a -> c) -> (b -> c) -> Tree a b -> [c]
  `a' is a rigid type variable bound by
      the type signature for
        preorder :: (a -> c) -> (b -> c) -> Tree a b -> [c]
In the first argument of `f', namely `a'
In the expression: f a
In the first argument of `(++)', namely `[f a]'

我知道我的问题是该函数的第一个参数的类型以及它需要如何成为 [c] 类型,但我终生无法弄清楚如何得到它。我尝试了 f a 周围的所有括号组合,没有括号,没有一个能成功运行。

【问题讨论】:

    标签: haskell tree traversal preorder


    【解决方案1】:

    根据您命名变量的方式,您的类型或函数调用混淆了 - 可能是类型。

    你说过Tree a b 在它的第一个参数中有一个b,但是preorder 的f 参数需要一个a。同样,Leaf 采用 a,但您在其上调用 g,它采用 b。

    这就是错误消息告诉您的内容:您传递给f 的第一个参数是b 类型,而它预期的是a。

    如果您将数据类型更改为:

    data Tree a b = Branch a (Tree a b) (Tree a b)
                  | Leaf b
    

    然后你的代码编译得很好。

    或者将preorder 更改为

    preorder  :: (a -> c) -> (b -> c) -> Tree a b -> [c]
    preorder f g (Leaf a) = [f a]
    preorder f g (Branch b left right) = [g b] ++ preorder f g left ++ preorder f g right
    

    【讨论】:

    • 非常感谢,我没有意识到我已经翻转了它们我对haskell还很陌生
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-21
    • 2014-09-26
    相关资源
    最近更新 更多