Ремонт принтеров, сканнеров, факсов и остальной офисной техники


назад Оглавление вперед




[19]

Привязка идентификаторов к исключениям в структурах подчинена тем же ограничениям, что и в ядре языка: они должны использовать только мономорфные типы. Спецификация исключения задает только его тип. Правила сопоставления с сигнатурой такие же, как и в случае переменных (за исключением того, что сложностей, связанных с полиморфными типами, здесь не возникает).

-structure S =

exception Barf

exception Crap = Barf

fun f(x) = if x=0 then raise Barf

else if x=l then raise Crap

>structure S =

exception Barf

exception Crap

val f = fn : int->int end

-S.f(O); Failure: Barf

-S.f(4);

>7 : int

Некоторые интересные дополнительные вопросы возникают в связи с объявлениями и спецификациями типов. Во-первых, рассмотрим прозрачное объявление типа в структуре - как, например, в первом примере этого раздела, где идентификатор t привязывался к типу int. Какова будет сигнатура этой структуры? Давайте рассмотрим, что получилось бы при гипотетическом режиме печати, упоминавшемся ранее:

-structure S =

type t = int val x = 3

fun f(x) = if x=0 then 1 else x*f(x-l) end;

>structure S =

type t = int

val f = fn

val x = 3 end


sig type t

val f : int->int

val x : int end

Спецификация для идентификатора t в структуре, к которой привязан S, есть просто type t, что говорит о том. что "значением" t является тип.

Если тип имеет параметр, его спецификация также очевидна:

-structure S =

type a t = а * int

val x = (true,3) end;

>structure S =

type a t = a * int

val x = (true,3) end

type a t

val x : bool * int end

Обратите внимание на форму спецификации для t.

Обе приведенные выше спецификации допустимы при записи сигнатуры. Но что произойдет при сопоставлении с такой сигнатурой? Рассмотрим следующий пример:

-signature SIG =

type a t

val x : int * bool end;

-structure S : SIG =

type a t = a * bool

val x = (3,true) end;

>structure S =


type a t = а * bool val х = (3,true): int * bool end

Структура, к которой привязывается S, сопоставима с сигнатурой SIG, поскольку S.t есть унарный (т.е. имеющий один аргумент) конструктор типа - как этого и требует SIG.

Если сигнатура задает некоторый конструктор типа, то этот конструктор может использоваться далее в сигнатуре. Например:

- signature SIG = sig

type a t

val x : int t end;

Эта сигнатура определяет класс структур, которые объявляют унарный конструктор типа t и переменную типа int t (для этого конструктора t).

Теперь давайте вернемся к приведенной выше структуре S и рассмотрим вопрос, сопоставима она или нет с сигнатурой SIG. В соответствии с неформальным описанием SIG, которое мы только что дали, она будет сопоставимой. Более строго, S будет сопоставима с SIG, потому что:

1.S.t, как и требуется, есть унарный конструктор типа.

2.Тип S.x есть int*bool. Поскольку, по определению S.t, int t равно int*bool, S.x соответствует спецификации int t.

Важно осознавать, что в процессе сопоставления с сигнатурой все идентификаторы типа в сигнатуре заменяются на соответствующие идентификаторы из структуры, и поэтому спецификация int t превращается в int S.t.

Упражнение 3.2.3 Какая сигнатура может быть сопоставлена со следующей структурой?

structure S = struct

type a t = а * int val x = (true, 3) end

При разработке программ полезно придерживаться правила замкнутости сигнатуры, которое требует, чтобы свободными идентификатора-



[стр.Начало] [стр.1] [стр.2] [стр.3] [стр.4] [стр.5] [стр.6] [стр.7] [стр.8] [стр.9] [стр.10] [стр.11] [стр.12] [стр.13] [стр.14] [стр.15] [стр.16] [стр.17] [стр.18] [стр.19] [стр.20] [стр.21] [стр.22] [стр.23] [стр.24] [стр.25] [стр.26] [стр.27] [стр.28] [стр.29] [стр.30] [стр.31] [стр.32]