我正在尝试遍历列表,并检查所有值是否等于0, 我得到的错误是:
* Couldn't match expected type `[Integer]' with actual type `Bool'
* In the second argument of `(:)', namely `allZero s'
In the expression: 0 : allZero s
In an equation for `allZero': allZero (0 : s) = 0 : allZero s
我的代码是:
allZero :: [Int] -> Bool
allZero (0:_) = True
allZero (0:s) = 0 : allZero s
allZero (_:s) = False;
allZero _ = False
我不明白为什么我会在allZero (0:s) = 0 : allZero s
行中向我提供此错误,并为其提供了正确的参数,即列表's'
答案 0 :(得分:10)
该行:
allZero (0:s) = 0 : allZero s
没什么意义,因为0 : allZero s
表示您正在构造一个列表,即一个数字列表。但是您想返回一个Bool
。
另外一行:
allZero (0:_) = True
也不正确,因为这意味着每个以0
开头的列表都满足该功能。但是在列表[0,1,4,2,5]
中,并非所有数字都是0
。
我们可以使用以下方法进行检查:
allZero (Num a, Eq a) => [a] -> Bool
allZero [] = True
allZero (0:s) = allZero s
allZero (_:_) = False
我们可以使用all :: Foldable f => (a -> Bool) -> f a -> Bool
并将其写为:
allZero :: (Num a, Eq a, Foldable f) => f a -> Bool
allZero = all (0 ==)
答案 1 :(得分:2)
我将尝试解释该错误和解决方案。解决方案应该是:
allZero :: [Int] -> Bool
allZero [] = True
allZero (x:xs) = (x == 0) && (allZero xs)
考虑两种模式。首先,如果没有元素,则全部为0,这是有意义的,即第一个模式[]
。
在第二种模式中,您询问第一种是否为0
,并说值&&
的所有其余元素必须为0
(使用递归)
在您的示例中:
allZero :: [Int] -> Bool
allZero (0:_) = True --Wrong, here you are saying if it start with 0, True, no matter what is next, and that's not correct
allZero (0:s) = 0 : allZero s -- this could be right along side with other patterns
allZero (_:s) = False -- this is wrong by sure, you are saying if a list has at list one element, False
allZero _ = False -- And this one has no sense among the others
您有很多模式,而且不正确。您可以将我的第一个答案更改为等效的答案:
allZero :: [Int] -> Bool
allZero [] = True
allZero (0:xs) = (allZero xs)
allZero _ = False