Понимание списка Haskell с помощью «x извлекается из функции»

#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. Нет, не заполнитель. Вы заявляете компилятору, что это требование должно работать для всех типов.