Являются ли типы продуктов и типы функций в SML конструкторами? - PullRequest
0 голосов
/ 24 апреля 2020

В книге Уллмана по SML:

Мы можем создавать новые типы из старых типов T1 и T2 следующим образом.

  1. T1 * T2 - это " Тип продукта, значения которого являются парами. Первый компонент пары имеет тип T1, а второй - тип T2.

  2. T1 -> T2 является типом «функции», значения которого являются функциями с типом домена T1 и типом диапазона T2.

  3. Мы можем создавать новые типы, следуя за типом, таким как T1, определенными идентификаторами, которые действуют как конструкторы типов.

    (a) Конструктор типа списка. То есть для каждого типа T1 существует другой список типа T1, значения которого представляют собой списки всех элементов типа T1.

    (b) Конструктор типа параметра. Для каждого типа T1 существует опция типа T1 со значениями NONE и SOME x, где x - любое значение типа T1.

    (c) Дополнительные конструкторы типов ref, array и vector.

Мне было интересно, считаются ли * в типах продуктов и -> в типах функций конструкторами типов?

Если нет, то почему?

Спасибо.

1 Ответ

1 голос
/ 24 апреля 2020

Это не так, но это в основном только по причинам, связанным с синтаксисом c:

  • * и -> являются ключевыми словами, а не идентификаторами (за исключением несвязанного использования * в качестве идентификатора, например, 3 * 4 = 12).
  • Мы пишем int * real и int -> real вместо (int, real) * и (int, real) ->.
  • Конструктор типа имеет фиксированное число: параметры (например, list всегда принимает один параметр - мы не можем записать (int, real) list - и int всегда не принимает ни одного), но int * real * char * string - это 4-кортеж. (Другими словами: * «перегружен» для любого типа n с набором n ≥ 2. Так что это похоже на бесконечно много конструкторов типа, скорее чем один.)

Но я не думаю, что есть какая-либо причина, по которой это должно быть таким. Можно представить версию Standard ML в параллельной вселенной, в которой:

  • определяет не * и -> как зарезервированные слова, а как идентификаторы в исходной базе (аналогично ref или int).
  • позволяет конструкторам типов быть инфиксными (аналогично тому, как 3 + 4 означает op+ (3, 4)) и объявлять * и -> как таковые.
  • не поддерживал нотацию * для продуктов трех и более типов, а интерпретировал int * real * char * string как ((int * real) * char) * string. (В нашей вселенной 'a * 'b * … * 'n - это просто синтактический c сахар для { 1: 'a, 2: 'b, …, 14: 'n }; возможно, в параллельной вселенной, которая не считается очень полезной для продуктов трех или более типов?)

На самом деле даже в нашей собственной вселенной мы можем написать:

type ('a, 'b) pair = 'a * 'b
type ('a, 'b, 'c) triple = 'a * 'b * 'c
type ('a, 'b) function = 'a -> 'b

, который создает конструкторы типов pair, triple и function, так что (int, real) pair является синонимом int * real, (int, real, char) triple является синонимом int * real * char, а (int, real) function является синонимом int -> real. (Не то, чтобы кто-то хотел этого.)

...