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


В 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
    it': it = (- 3) 2

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

4 3

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)

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