无法将预期类型“ [Integer]”与实际类型“ Bool”匹配

时间:2019-11-04 14:11:31

标签: list haskell recursion functional-programming

我正在尝试遍历列表,并检查所有值是否等于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'

2 个答案:

答案 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