我的任务有问题:我正在尝试编写一个代码,列出我告诉他的所有节点值(例如,所有节点值为4的整个列表)。 / p>
我写了以下内容:
findValue :: a -> (MyTree a) -> [a]
findValue x Leaf = []
findValue x (Node a l r)
|a == x = x++(findValue x l)++(findValue x r)
|a /= x = (findValue x l)++(findValue x r)
我已将树定义如下:
data MyTree a = Leaf | Node a (MyTree a) (MyTree a)
我收到以下错误消息:
Couldn't match expected type ‘[a]’ with actual type ‘a’
‘a’ is a rigid type variable bound by
the type signature for findValue :: a -> MyTree a -> [a]
at assignment.hs:10:14
Relevant bindings include
r :: MyTree a (bound at assignment.hs:12:25)
l :: MyTree a (bound at assignment.hs:12:23)
a :: a (bound at assignment.hs:12:21)
x :: a (bound at assignment.hs:12:11)
findValue :: a -> MyTree a -> [a]
(bound at assignment.hs:11:1)
In the first argument of ‘(++)’, namely ‘x’
In the expression: x ++ (findValue x l) ++ (findValue x r)
如果有人向我解释错误消息,我会很高兴。提前谢谢!
答案 0 :(得分:2)
(++)
的类型为[a] -> [a] -> [a]
,但x
的类型为a
。因此你可以写
x : (findValue x l) ++ (findValue x r)
(使用" cons"运算符(:) :: a -> [a] -> [a]
)或
[x] ++ (findValue x l) ++ (findValue x r)
以下是您应该自行确定的方法:
错误说Couldn't match exptected type '[a]' with actual type 'a' ...
in the first argument of '(++)', namely 'x'
这意味着参数x
到(++)
(在指示的行上)应该具有类型[a]
( 预期类型),但实际上有a
类型(推断类型)。
然后,您应该查找(++)
的类型签名,看看问题可能是什么(例如使用hoogle,hayoo或ghci)在您的情况下,问题是(++)
的第一个和第二个参数的类型不一样,但它们应该是。
答案 1 :(得分:2)
想想你在做什么。 findValue
属于a -> MyTree a -> [a]
类型,这意味着x
属于a
类型。
但是,(++)
运算符属于[a] -> [a] -> [a]
类型,但您正在编写x ++ (findValue x l) ++ (findValue x r)
。因此它会给你一个错误说:
Couldn't match expected type ‘[a]’ with actual type ‘a’
‘a’ is a rigid type variable bound by
the type signature for findValue :: a -> MyTree a -> [a]
at assignment.hs:10:14
Relevant bindings include
r :: MyTree a (bound at assignment.hs:12:25)
l :: MyTree a (bound at assignment.hs:12:23)
a :: a (bound at assignment.hs:12:21)
x :: a (bound at assignment.hs:12:11)
findValue :: a -> MyTree a -> [a]
(bound at assignment.hs:11:1)
In the first argument of ‘(++)’, namely ‘x’
In the expression: x ++ (findValue x l) ++ (findValue x r)
错误消息清楚地表明它是Couldn't match expected type ‘[a]’ with actual type ‘a’
。它进一步告诉你问题在哪里,In the first argument of ‘(++)’, namely ‘x’
。它甚至会告诉您在哪里找到该表达式In the expression: x ++ (findValue x l) ++ (findValue x r)
。
Haskell错误消息可能看起来非常可怕,但它们实际上非常有用且容易理解。不要让像‘a’ is a rigid type variable bound by
这样的短语吓到你。
我理解当你读到的第二句话是你不理解的东西时很容易放弃,而且我理解在SO上发表关于它的问题会更容易。帮自己一个忙,不要。了解如何理解错误消息。
给一个男人一条鱼,他会吃一天。教一个人钓鱼,他一辈子都会吃。
顺便说一下,你为什么需要findValue
类型的a -> MyTree a -> [a]
函数?拥有:
hasValue :: a -> MyTree a -> Bool
hasValue x Leaf = False
hasValue x (Node a l r)
| a == x = True
| otherwise = findValue x l || findValue x r
numValue :: a -> MyTree a -> Int
numValue x Leaf = 0
numValue x (Node a l r)
| a == x = depth + 1
| otherwise = depth
where depth = findValue x l + findValue x r
对我来说,拥有findValue
函数没有任何意义,因为给定findValue x t
结果是:
False
或True
)。因此hasValue
。重复的x
值列表,在这种情况下只有长度很重要。因此numValue
。
findValue :: a -> MyTree a -> [a]
findValue x t = replicate (numValue x t) x