【问题标题】:Counting elements in a tree in Haskell在 Haskell 中计算树中的元素
【发布时间】:2011-01-14 02:51:30
【问题描述】:

基本上我已经创建了一个多态树数据类型,我需要一种计算给定树中元素数量的方法。这是我的 Tree 数据类型的声明:

data Tree a = Empty
| Leaf a
| Node (Tree a) a (Tree a)
deriving (Eq, Ord, Show)

所以我可以像这样定义一个 Ints 树:

t :: Tree Int
t = Node (Leaf 5) 7 (Node (Leaf 2) 3 (Leaf 7))

但是,我需要一个函数来计算其中一个列表中的元素数量。我已经定义了这个递归函数,但是我得到了错误“推断的类型不够通用”:

size :: Tree a -> Int
size Empty   = 0
size (Leaf n)    = 1
size (Node x y z)    = size x + size y + size z

这里有什么我不应该做的吗?

【问题讨论】:

    标签: haskell recursion functional-programming count


    【解决方案1】:

    我觉得只是你写的时候打错了

    size (Node x y z) = size x + size y + size z
    

    应该是

    size (Node x y z) = size x + size z + 1
    

    因为 y 不是子树,而只是存储的元素。

    或者说更清楚

    size (Node left elem right) = size left + size right + 1
    

    从技术上讲,您的错误发生是因为术语 size y 只有在 y 再次是可以计算其大小的树时才有意义。因此这个子句的类型会被推断为Tree (Tree a) -> Int,也就是说,与实际的Tree a -> Int相比,不一般 够了

    【讨论】:

    • 不会是size x + 1 + size z吗?因为他在计算元素,每个节点都包含一个元素。
    • @BaroqueBobcat:啊……是的;)
    • 实际上size 的类型是无限类型Tree (Tree (Tree ... ))) -> Int。在这种情况下,一个好的技巧是总是忽略有问题的类型签名,让编译器告诉你它认为什么应该是正确的类型。在这种情况下,GHC 告诉我它正在尝试构造一个无限类型...
    • @yatima2975:当然可以,但正如我所说,“将推断出该子句的类型”,这足以解释此案。
    • 嘿@Dario,我阅读了你的解释,但是,元素怎么算为“1”?我以为我们只计算子树的数量?
    【解决方案2】:

    看你最后一个子句:看左边,Node x y zy 的类型是什么? size y 有意义吗?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-03
      • 1970-01-01
      相关资源
      最近更新 更多