在二叉树示例中尝试练习时无限类型错误

时间:2016-03-10 19:10:12

标签: elm

在练习2 here中,我向编译器提供了这个解决方案并得到了无限类型错误。

flatten : Tree a -> List a
flatten tree =
  case tree of
    Empty -> []
    Node v left right ->
      [v] :: flatten left :: flatten right

这与我第一次练习的解决方案似乎没有什么不同:

sum : Tree Int -> Int
sum tree =
  case tree of
    Empty -> 0
    Node v left right ->
        v + sum left + sum right

我想知道这个问题是否与操作顺序有关,所以我添加了parens以确保在flatten之前评估::,但这似乎没有什么区别:

flatten : Tree a -> List a
flatten tree =
  case tree of
    Empty -> []
    Node v left right ->
      [v] :: (flatten left) :: (flatten right)

所以现在我只是难倒了。

1 个答案:

答案 0 :(得分:4)

::cons operator,这意味着它会将单个元素添加到列表中。它的类型签名是a -> List a -> List a。这意味着这不是有效代码,因为第一个参数[v]是一个列表:

[v] :: flatten left :: flatten right -- invalid!

如果要连接两个列表,请使用连接运算符:++。您可以在示例中将::替换为++以使其编译:

[v] ++ flatten left ++ flatten right

表示该行的另一种方法是连接两个列表,然后使用v运算符在cons前面添加列表。

v :: flatten left ++ flatten right

-- The following is the same as above, but with parentheses showing precedence
v :: (flatten left ++ flatten right)

当然,有更有效的方法可以做到这一点,但它突出了cons和连接之间的区别。

您的sum示例的工作原因是因为它返回的是int而不是int的列表。您在sum中返回的类型与树中的值相同,因此您最终得到的是聚合,而不是另一个列表。