Используя открытые объединения вне модуля, они были определены в - PullRequest
5 голосов
/ 27 октября 2011

Почему это работает нормально?

module Account = struct

 type account_type = Current of float | Savings of float

end

let sarah = Account.Current 100.0;;

В то время как последняя строка в следующем производит Error: syntax error?

module Account = struct

  type 'a account_type = [> `Current of float | `Savings of float ] as 'a

end

let pete = Account.`Current 100.0;;

То есть, почему я не могу использовать открытый тип соединения вне модуля, не открывая модуль? Я должен сказать, что узнал, что изменил последнюю строку на:

open Account;;
let pete = `Current 100.0;;

работает нормально, но, очевидно, это громоздко, если я много использую account_type, или, в качестве альтернативы, я должен открыть Account в начале любого раздела кода, где используется account_type, что означает, что я пожертвую абстракцию, которую я получу, используя подпись для Account
Я просмотрел несколько руководств по OCaml, а также документацию INRIA, и не могу найти упоминания о том, как вы это делаете.
Можно ли избежать необходимости открывать модуль каждый раз, когда я хочу использовать account_type?

Заранее спасибо,

Zach

Ответы [ 2 ]

6 голосов
/ 27 октября 2011

Во втором примере вам вообще не нужно open Account, синтаксис просто `Current 100.0.Полиморфный вариантный тег не участвует ни в каком конкретном типе.Тип `Current равен [> `Current ], это (>) означает, что тип по крайней мере `Current, и, поскольку это подмножество типа, принятого функцией, он скомпилируется просто отлично.Вы можете передать это же значение ряду функций, которые принимают полиморфный вариант с тем же именем.Конечно, не хватает статической информации о типах, и ошибки и ситуации при наборе могут стать довольно сложными.

Повторное использование кода через полиморфные варианты говорит о некоторых преимуществах и вариантах их использования.

5 голосов
/ 27 октября 2011

Полиморфные вариантные константы, такие как `Current, определены глобально, аналогично целочисленным константам.Вы бы не сказали Account.10, чтобы ссылаться на целое число 10 внутри модуля * 1003. *

Это сила (и слабость) полиморфных вариантов, вы можете использовать их, не определяя их (как вы не делаете)перед его использованием нужно определить 10).

Итак, как говорит nlucaroni, вам не нужно открывать модуль Account, чтобы получить доступ к `Current.

В отличие отцелые числа, полиморфные варианты также могут принимать параметры (как в вашем `Current 100.0).Но число параметров и их типы не являются фиксированными, и они могут даже варьироваться для одного и того же конструктора в разных местах кода.Отсюда и сложности, упомянутые nlucaroni.

[Примечание о форматировании: чтобы получить одинарные обратные кавычки `, отображаемые в тексте с использованием пишущей машинки, соглашение об уценке заключается в использовании двойных обратных кавычек для включения текста.Это оставляет одиночные обратные кавычки внутри текста.Или, по крайней мере, это работает для меня.]

...