Нет экземпляра для ошибки

Следуя примеру в http://en.wikibooks.org/wiki/Haskell/Beginning

Prelude> let abs x = if x < 0 then -x else x
Prelude> abs 5
5
Prelude> abs -3

<interactive>:1:6:
    No instance for (Num (a0 -> a0))
      arising from the literal `3'
    Possible fix: add an instance declaration for (Num (a0 -> a0))
    In the second argument of `(-)', namely `3'
    In the expression: abs - 3
    In an equation for `it': it = abs - 3

Что случилось?


person zaf    schedule 03.06.2011    source источник
comment
Объяснение сообщения об ошибке, просто для справки в будущем: a0 -> a0 является типом abs. (Введите :t abs в свой ghci, чтобы увидеть его.) В сообщении об ошибке говорится, что этот тип a0 -> a0 не является экземпляром класса типов Num, так как только Num могут быть вычтены друг из друга, и в любом случае 3 означает, что первый аргумент должен быть какого-то типа в Num. (В ghci введите :t (-) и :t 3, чтобы увидеть, что происходит.) Строка во втором аргументе `(-)', а именно `3', наиболее показательна: она показывает, что - обрабатывается как инфиксный оператор с два аргумента, а не унарный минус.   -  person ShreevatsaR    schedule 03.06.2011


Ответы (2)


Haskell думает, что вы пытаетесь вычесть 3 из abs, и жалуется, что abs не является числом. Вам нужно добавить круглые скобки при использовании унарного оператора отрицания:

abs (-3)
person hammar    schedule 03.06.2011
comment
Ваше здоровье. Документация викиучебников кажется неверной в нескольких местах. - person zaf; 12.06.2011

Переводчик думает, что вы имеете в виду abs - 3, а не abs (-3). Вам нужны скобки, чтобы устранить неоднозначность кода и убедиться, что вы собираетесь использовать унарную функцию «-», а не оператор вычитания.

person MGwynne    schedule 03.06.2011