Опубликован: 19.09.2008 | Доступ: свободный | Студентов: 658 / 70 | Оценка: 4.50 / 5.00 | Длительность: 21:25:00
Лекция 4:

Выражения

3.4 Применение операторов

exp -> exp1 qop exp2
| - exp (префиксное отрицание)
qop -> qvarop | qconop (квалифицированный оператор)

Перевод:

выражение ->      выражение1 квалифицированный-оператор выражение2
| - выражение (префиксное отрицание)
квалифицированный-оператор -> квалифицированный-оператор-переменной | квалифицированный-оператор-конструктора (квалифицированный оператор)

Форма e1 qop e2 представляет собой инфиксное применение бинарного оператора qop к выражениям e1 и e2.

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

Префиксный оператор отрицания имеет тот же приоритет, что и инфиксный оператор -, определенный в Prelude (см. таблицу в п.4.4.3). Поскольку e1-e2 при разборе интерпретируется как инфиксное применение бинарного оператора -, для альтернативной интерпретации нужно писать e1(-e2). Аналогично, (-) является синтаксической записью (\ x y -> x-y), как и любой инфиксный оператор, и не обозначает (\ x -> -x) - для этого нужно использовать negate.

Трансляция:

Выполняются следующие тождества:

e1 op e2=(op) e1 e2-e= negate (e)

3.5 Сечения

aexp -> ( expi+1 qop(a,i) ) (левое сечение)
| ( lexpi qop(l,i) ) (левое сечение)
| ( qop(a,i)<> expi+1 ) (правое сечение)
| ( qop(r,i)< -> < -> rexpi ) (правое сечение)

Перевод:

выражение-аргумента -> ( выражениеi+1 квалифицированный-оператор(a,i) ) (левое сечение)
| ( левое-сечение-выраженияi квалифицированный-оператор(l,i) ) (левое сечение)
| ( квалифицированный-оператор(a,i)<-> выражениеi+1 ) (правое сечение)
| ( квалифицированный-оператор(r,i)<-> правое-сечение-выраженияi ) (правое сечение)

Сечения записываются в виде ( op e ) или ( e op ), где op - бинарный оператор, а e - выражение. Сечения представляют собой удобный синтаксис для записи частичного применения бинарных операторов.

Синтаксические правила приоритетов применяются к сечениям следующим образом. (op e) допустимо, если и только если (x op e) при разборе интерпретируется так же, как и (x op (e)) ; аналогично для (e op). Например, (*a+b) синтаксически недопустимо, но (+a*b) и (*(a+b)) допустимы. Поскольку оператор (+) левоассоциативен, (a+b+) синтаксически правильно, а (+a+b) - нет, его можно правильно записать в виде (+(a+b)). В качестве другого примера рассмотрим выражение

(let n = 10 in n +)

которое является недопустимым в соответствии с мета-правилом для let/лямбда (раздел "3" ). Выражение

(let n = 10 in n + x)

при разборе интерпретируется как

(let n = 10 in (n + x))

вместо

((let n = 10 in n) + x)

Поскольку - интерпретируется в грамматике специальным образом, (- exp) является не сечением, а применением префиксного оператора отрицания, в соответствии с описанием в предыдущем разделе. Тем не менее, имеется функция subtract, определенная в Prelude таким образом, что (subtract exp) эквивалентно недопустимому ранее сечению. Для той же цели может служить выражение (+ (- exp)).

Трансляция:

Выполняются следующие тождества:

(op e)= \ x -> x op e

(e op)= \ x -> e op x

где op - бинарный оператор, e - выражение, а x - переменная, которая не является свободной в e.

3.6 Условные выражения

exp -> if exp1 then exp2 else exp3

Перевод:

выражение -> if выражение1 then выражение2 else выражение3

Условное выражение имеет вид if e1 then e2 else e3 и возвращает: значение e2 - если значение e1 равно True, e3 - если e1 равно False, и _|_ - иначе.

Трансляция:

Выполняются следующие тождества:

if e1 then e2 else e3= case e1 of { True -> e2 ; False -> e3 }

где True и False - конструкторы с нулевым числом аргументов из типа Bool, определенные в Prelude. Тип e1 должен быть Bool, e2 и e3 должны иметь тот же тип, который также является типом всего условного выражения.