Префиксная форма унарного оператора в Haskell

В GHCi:

  1. Прелюдия> (+3) 2
    5
  2. Прелюдия> (* 3) 2
    6
  3. Прелюдия> (/ 3) 2
    0,6666666666666666
  4. Прелюдия> (-3) 2
    Нет экземпляра для (Num (t -> t1))
    вытекающие из буквального 3' at <interactive>:1:2
    Possible fix: add an instance declaration for (Num (t -> t1))
    In the expression: 3
    In the expression: (- 3) 2
    In the definition of
    это ': это = (- 3) 2

Как я могу исправить последний, чтобы он возвращал -1?

4 ответа

Решение

Грамматика Хаскелла не позволяет вам использовать - как это. Использовать subtract функция вместо:

(subtract 3) 2

В качестве сноски к ответу grddev, вот соответствующий параграф из отчета Haskell 98:

Специальная форма -e обозначает отрицание префикса, единственный префиксный оператор в Haskell, и является синтаксисом для negate (e), Бинарный - оператор не обязательно относится к определению - в прелюдии; это может быть восстановлено модульной системой. Тем не менее, одинарный - всегда будет ссылаться на negate функция определена в прелюдии. Там нет никакой связи между местным значением - оператор и унарное отрицание.

Это то, что расстроило меня, когда я впервые столкнулся с этим: я не мог понять, почему операторы вели себя так по-разному в этом контексте, когда :info (+) а также :info (-) выглядел в основном идентично.

Вы могли бы использовать subtract, как предполагает grddev, или вы можете просто определить новый инфиксный оператор:

Prelude> let (#) = (-)
Prelude> (# 3) 2
-1

subtract имеет преимущество быть знакомым с другими людьми, которые могут читать ваш код.

Ты можешь сделать

(-) 3 2

но это даст вам 1. Чтобы иметь -1, вам нужно связать 3 со вторым аргументом -, который вы можете сделать, используя

flip (-) 3 2

Если вы хотите сохранить свою первоначальную форму, вы всегда можете добавить негатив:

(+ -3)

Это не красиво, но немного больше подходит вашему образцу.

Другие вопросы по тегам