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

#haskell #ghci

#haskell #ghci

Вопрос:

Следуя примеру в 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
  

Что не так?

Комментарии:

1. Объяснение сообщения об ошибке, просто для дальнейшего использования: a0 -> a0 это тип abs . (Введите :t abs в вашем ghci, чтобы увидеть это.) В сообщении об ошибке говорится, что этот тип a0 -> a0 не является экземпляром класса type Num , поскольку только Num s могут быть вычтены друг из друга, и в любом случае 3 означает, что первый аргумент должен быть некоторого типа в Num . (Введите в ghci :t (-) и :t 3 , чтобы посмотреть, что происходит.) Строка «во втором аргументе `(-)’, а именно `3′» наиболее показательна: она показывает, что - обрабатывается как инфиксный оператор с двумя аргументами, а не с унарным минусом.

Ответ №1:

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

 abs (-3)
  

Комментарии:

1. Приветствия. Документация wikibooks, похоже, некорректна в нескольких местах.

Ответ №2:

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