Почему Хаскелл интерпретирует мой тип NUM как перечисление?

StackOverflow https://stackoverflow.com/questions/1533585

Вопрос

Я пытаюсь собрать следующую функцию в Хаскелле, чтобы имитировать дифференциацию полинома, чьи константы указаны в числовом списке:

diff :: (Num a) => [a] -> [a]
diff [] = error "Polynomial unspecified"
diff coeff = zipWith (*) (tail coeff) [0..]

Haskell отказывается скомпилировать его, давая мне следующую причину:

Could not deduce (Enum a) from the context (Num a)
 arising from the arithmetic sequence `0 .. ' at fp1.hs:7:38-42
Possible fix:
 add (Enum a) to the context of the type signature for `diff'
In the third argument of `zipWith', namely `[0 .. ]'
In the expression: zipWith (*) (tail coeff) ([0 .. ])
In the definition of `diff':
diff coeff = zipWith (*) (tail coeff) ([0 .. ])

Почему Haskell относится к [0..] Список как тип перечисления, и как я могу это исправить. Имейте в виду, что я хочу воспользоваться ленивой оценкой здесь, отсюда и бесконечный список.

Это было полезно?

Решение

[0..] это синтаксический сахар для enumFrom 0, определено в классе Enum. Анкет Потому что вы хотите собрать список aс [0..] Компилятор требует a быть в классе Enum.

Вы можете добавить Enum a на тип подписи функции или обойти ее, генерируя [0..] :: [Integer] и использование fromInteger (что определено в классе Num) чтобы получить [a] От этого:

diff :: (Num a) => [a] -> [a]
diff [] = error "Polynomial unspecified"
diff coeff = zipWith (*) (tail coeff) (map fromInteger [0..])

Другие советы

Правильный тип diff должен быть

diff :: (Num a, Enum a) => [a] -> [a]

Потому что использование [x..] Требуется тип экземпляра Enum.

[0..] это сокращение enumFrom 0 Глянь сюда

Вот краткое изложение того, что компилятор видит, когда он смотрит на эту функцию:

  • 0 ..] - это список вещей, которые имеют экземпляры NUM и Enum. Это должно быть число из -за «0», и это должно быть перечисление из -за «..»
  • Меня просят подать заявку (*) к элементам коэффициента и [0 ..] один за другим. Поскольку оба аргумента (*) должны быть одинаковым типом, а [0 ..] имеет экземпляр для Enum, коэффициент также должен иметь экземпляр для Enum.
  • Ошибка! Тип сигнатура только Diff упоминает, что у коэффициента есть экземпляр для NUM, но я уже определил, что он должен, по крайней мере, иметь экземпляр для Enum.
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top