-
LexicalNegation -
- Версия:
-
9.0.1
Определяет, обозначает ли знак минуса отрицание при лексическом анализе, проверяя наличие пробелов вокруг него.
В Haskell 2010 знак минуса обозначает отрицание, если слева от него нет выражения. Рассмотрим x = - 5 и y = 2 - 5. В x между = и - нет выражения, поэтому минус обозначает отрицание, тогда как в y слева от минуса находится 2, поэтому он обозначает вычитание.
Это приводит к некоторым синтаксическим аномалиям:
-
(% x)— это операторная секция для любого оператора(%), кроме(-).(- x)— это отрицаниеx, а не правая операторная секция вычитания. Следовательно, такую секцию невозможно записать, поэтому рекомендуется вместо неё писать(subtract x). - Отрицательные числа необходимо заключать в скобки, когда они используются в качестве аргумента функции.
f (-5)— корректная запись, тогда какf -5разбирается как(-) f 5.
Эта проблема частично устраняется расширением NegativeLiterals. Если оно включено, -5 разбирается как отрицательное число 5 независимо от контекста, поэтому f
-5 работает ожидаемым образом. Однако это применимо только к литералам, поэтому f -x или f -(a*2) по-прежнему разбираются как вычитание.
С расширением LexicalNegation обе аномалии устраняются:
-
(% x)— это операторная секция для любого оператора(%)без исключений, если между%иxесть пробел. - В
f -x-xразбирается как отрицаниеxдля любого синтаксически атомарного выраженияx(переменной, литерала или выражения в скобках). - Префиксный оператор
-имеет более высокий приоритет, чем любой инфиксный оператор.-a % bразбирается как(-a) % bнезависимо от приоритета%.
Это означает, что (- x) — правая операторная секция вычитания, тогда как (-x) — отрицание x. Обратите внимание, что типы этих выражений часто различаются ((- x) может иметь тип Int -> Int, тогда как (-x) будет иметь тип Int), поэтому пользователи, перепутавшие одно с другим, скорее всего, получат ошибку компиляции.
При использовании расширения LexicalNegation отрицательные литералы преобразуются без negate. То есть -123 обозначает fromInteger (-123), а не negate (fromInteger 123). Это делает LexicalNegation полноценной заменой NegativeLiterals.