#list #function #haskell #types
#Список #функция #haskell #типы
Вопрос:
Приведенный ниже код, начинающийся с digits
, возвращает список целых чисел. Код, начинающийся с altSumOfDigits
, должен возвращать точно такой же список, но вместо этого Prelude жалуется на ошибку типа, которую я на данный момент не понимаю.
Couldn't match expected type `a' against inferred type `Integer'
digits' :: Integer -> [Integer]
digits' 0 = []
digits' x = (x `mod` 10) : digits' (x `div` 10)
digits :: Integer -> [Integer]
digits 0 = [0]
digits x = reverse $ digits' x
altSumOfDigits :: Integer -> [a]
altSumOfDigits num = [ x | x <- (digits num)]
(Я знаю, что altSumOfDigits num = [ x | x <- (digits num)]
это довольно бесполезно в этой форме. Позже я собираюсь расширить его функциональность с помощью if-выражения и операций над одиночными целыми числами.)
Какие-либо объяснения, почему это не работает?
Ответ №1:
Измените (или удалите) тип altSumOfDigits
, чтобы возвращать [Integer]
.
Включение ошибки в вопрос является хорошей формой, и вот она:
Couldn't match type `a' with `Integer'
Тип altSumOfDigits
принимает список Integer
, но возвращает список любого типа a
в соответствии с типом, который вы объявили. Таким образом, он полиморфен по типу возвращаемого значения.
Однако вы вызываете digits
изнутри altSumOfDigits
, которая должна возвращать только список Integer
. Таким образом, ваш altSumOfDigits
не может вернуть ничего, кроме списка [Integer]
.
Комментарии:
1. Таким образом, тип [a] — это не просто супертип [Integer] . Я думал, что [a] или solo a (или что-либо с a) может быть заполнителем для любого другого типа. Спасибо за ваш улов.
2. Нет, не заполнитель. Вы заявляете компилятору, что это требование должно работать для всех типов.