Не удалось сопоставить ожидаемый тип `[Integer] с фактическим типом` Bool ' - PullRequest
3 голосов
/ 04 ноября 2019

Я пытаюсь выполнить итерацию по списку и проверяю, равны ли все значения 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 ]

10 голосов
/ 04 ноября 2019

Строка:

allZero (0:s) = <b>0 : allZero s</b>

не имеет большого смысла, поскольку 0 : allZero s означает, что вы строите список, список чисел. Но вы хотите вернуть Bool.

Кроме того, строка:

allZero <b>(0:_)</b> = True

также неверна, поскольку это означает, что каждый список, начинающийся с 0, удовлетворяетфункции. Но в списке [0,1,4,2,5] не все числа 0.

Мы можем проверить это с помощью:

allZero (Num a, Eq a) => [a] -> Bool
allZero [] = True
allZero (0:s) = <b>allZero s</b>
allZero (_:_) = False

Мы можем использовать all :: Foldable f => (a -> Bool) -> f a -> Bool и запишите это как:

allZero :: (Num a, Eq a, Foldable f) => f a -> Bool
allZero = <b>all (0 ==)</b>
2 голосов
/ 04 ноября 2019

Я постараюсь объяснить ошибку и решение. Решение должно быть:

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 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...