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

Выражения

3.16 Сигнатуры типов выражений

exp -> exp :: [context =>] type

Перевод:

выражение -> выражение :: [контекст => ] тип

Сигнатуры типов выражений имеют вид e :: t, где e - выражение, а t - тип (раздел "4.1.2" ); они используются для явного указания типа выражения, в частности, для того чтобы разрешить неоднозначность типов из-за перегрузки (см. раздел "4.3.4" ). Значением выражения является значение exp. Как и с обычными сигнатурами типов (см. раздел "4.4.1" ), объявленный тип может быть более частным, чем основной тип, выводимый из exp, но будет ошибкой указать тип, который окажется более общим или не сопоставимым с основным типом.

Трансляция:

e :: t = let { v :: t; v = e } in v

3.17 Сопоставление с образцом

Образцы появляются в лямбда-абстракциях, определениях функций, связываниях с образцом, описаниях списков, do-выражениях и case-выражениях. Тем не менее, первые пять из них в конечном счете транслируются в case-выражения, поэтому достаточно ограничиться определением семантики сопоставления с образцом для case-выражений.

3.17.1 Образцы

Образцы имеют следующий синтаксис:

pat -> var + integer (образец упорядочивания)
| pat0
pati -> pati+1 [qconop(n,i) pati+1]
| lpati
| rpati
lpati -> (lpati | pati+1) qconop(l,i) pati+1
lpat6 -> - (integer | float) (отрицательный литерал)
rpati -> pati+1 qconop(r,i) (rpati | pati+1)
pat10 -> apat
| gcon apat1 ... apatk (число аргументов конструктора gcon = k, k >= 1 )
apat -> var [@ apat] ("такой как"-образец)
| gcon (число аргументов конструктора gcon = 0 )
| qcon { fpat1 , ... , fpatk } (именованный образец, k >= 0 )
| literal
| _ (любые символы)
| ( pat ) (образец в скобках)
| ( pat1 , ... , patk ) (образец кортежа, k >= 2 )
| [ pat1 , ... , patk ] (образец списка, k >= 1 )
| ~apat (неопровержимый образец)
fpat -> qvar = pat

Перевод:

образец ->      переменная + целый-литерал (образец упорядочивания)
| образец0
образецi -> образецi+1 [квалифицированный-оператор-конструктора(n,i) образецi+1]
| левый-образецi
| правый-образецi
левый-образецi -> (левый-образецi | образецi+1) квалифицированный-оператор-конструктора(l,i) образецi+1
левый-образец6 -> - (целый-литерал | литерал-с-плавающей-точкой) (отрицательный литерал)
правый-образецi -> образецi+1 квалифицированный-оператор-конструктора(r,i) (правый-образецi | образецi+1)
образец10 -> такой-как-образец
| общий-конструктор такой-как-образец1 ... такой-как-образецk (число аргументов конструктора gcon = k, k >= 1 )
такой-как-образец -> переменная [@ такой-как-образец] ("такой как"-образец)
| общий-конструктор (число аргументов конструктора gcon = 0)
| квалифицированный-конструктор { образец-с-именем1 , ... , образец-с-именемk } (именованный образец, k >= 0 )
| литерал
| _ (любые символы)
| ( образец ) (образец в скобках)
| ( образец1 , ... , образецk ) (образец кортежа, k >= 2 )
| [ образец1 , ... , образецk ] (образец списка, k>=1 )
| ~ такой-как-образец (неопровержимый образец)
образец- -> квалифицированная-переменная = образец

Число аргументов конструктора должно соответствовать числу образцов, связанных с ним; нельзя сопоставлять частично примененный конструктор.

Все образцы должны быть линейными : ни одна переменная не может появляться более одного раза. Например, следующее определение недопустимо:

f (x,x) = x - ЗАПРЕЩЕНО; x дважды используется в образце

Образцы вида var@pat называются "такими как" - образцами, и позволяют использовать var в качестве имени для значения, сопоставляемого pat. Например,

case e of { xs@(x:rest) -> if x==0 then rest else xs }

эквивалентено

let { xs = e } in
  case xs of { (x:rest) -> if x==0 then rest else xs }

Образцы вида _ обозначают группы любых символов и полезны, когда некоторая часть образца не используется в правой части. Это как если бы идентификатор, не используемый где-либо в другом месте, был помещен на свое место. Например,

case e of { [x,_,_]  ->  if x==0 then True else False }

эквивалентно

case e of { [x,y,z]  ->  if x==0 then True else False }