我遇到了这个定义的错误,不知道为什么。
定义:
data Tree a = Leaf a | Node a [Tree a]
deriving (Eq,Show)
功能:
count :: Tree a -> Integer
count (Leaf a) = 0
count (Node l r) = 1 + count l + count r
错误:
Couldn't match expected type ‘Tree a2’
with actual type ‘[Tree a]’
• In the first argument of ‘count’, namely ‘r’
In the second argument of ‘(+)’, namely ‘count r’
In the expression: 1 + count l + count r
• Relevant bindings include
r :: [Tree a]
2条答案
按热度按时间llycmphe1#
考虑在一个简单的测试输入上评估这个函数时会发生什么。
Node 1 [Leaf 2, Leaf 3]
与第一个模式Leaf a
不匹配,因此我们跳过第一个子句。Node 1 [Leaf 2, Leaf 3]
与第二个模式Node l r
匹配,因此我们采用第二个子句。l
是类型为Int
的1
。r
是类型为[Tree Int]
的[Leaf 2, Leaf 3]
。1 + count 1 + count [Leaf 2, Leaf 3]
。现在有两个矛盾:
1.在
count l
中,Int
与Tree a
不匹配,这可以通过从求和中完全移除count l
来解决,因为1
已经代表了对Node
的计数。1.在
count r
中,[Tree a]
与Tree a
不匹配。这可以通过使用map
来计算所有子树的大小,并使用sum
将它们相加来解决。一些改进是可能的。
l
和r
不是很有用的名字。l
看起来像一个左子树,但它是树中的元素;r
看起来像一个右子树,但它是一个子树列表。现在,这在一个更复杂的例子中起作用。
count largerExample
是3。7gcisfzg2#
错误消息非常清楚:您正在尝试将
count
函数应用于[Tree a]
值,但它需要Tree a
值(只是一棵树,而不是树列表)。要使它编译,你需要以某种方式处理这个列表。你可以像这样使用
Data.List.foldl
函数: