Как сделать полиморфные варианты Ocaml приватными - PullRequest
0 голосов
/ 04 сентября 2018

Я хотел бы переключить некоторые из моих типов на использование полиморфных вариантов Ocaml, учитывая их с открытой рекурсией, в то же время сохраняя при этом соблюдение моих существующих частных неполиморфных типов, а также проверки на исчерпывающий характер при сопоставлении с образцом.

Мой продукт - это компилятор, поэтому набор типов изменяется с помощью различных алгоритмов, в настоящее время я должен включить все конструкторы с теми, которые не должны возникать, "assert false" ed.

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

Я не совсем уверен, возможно ли или целесообразно ли объединять «специальные» подмножества конструкторов с конфиденциальностью. Любые предложения относительно того, насколько это практично?

РЕДАКТИРОВАТЬ: простые примеры типов:

(* open *)
type 'a x' = [`A | `B of 'a]

(* closed *)
type x = private 'u x' as 'u

(* open extension *)
type 'a y' = ['a x' | `C of 'a] 

(* closed extension *)
type y = private 'u y' as 'u 

let mkA () = `A
let mkB' (a:'a x') = `B a

(* how to do this? *)
let mkB (a:x) = mkB' (a :> 'a x')

При открытой рекурсии функции конструктора должны следовать шаблону открытых / закрытых типов. Клиент только увидит закрытые версии. Это означает, что в отличие от моей нынешней системы, где достаточно одной функции конструктора, мне теперь нужна одна для каждого закрытого типа, для каждого типа, в котором содержится конструктор.

Даже если я смогу понять, как это сделать, что довольно сложно, если вы скажете 6 взаимозависимых типов, ВСЕ из которых используют открытую рекурсию, что приводит к экспоненциальному взрыву возможных комбинаций, неясно, является ли это преимуществом. по сравнению с просто принятием проверок во время выполнения. У меня заняло около 2 часов, чтобы добавить новый конструктор, потому что каждое сопоставление с образцом терпит неудачу с ошибкой исчерпанности и должно быть исправлено ... даже если новый конструктор не используется на этом этапе компиляции. '

1 Ответ

0 голосов
/ 07 сентября 2018

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

module M : sig
  (* open *)
  type 'a x' = [`A | `B of 'a]
  (* closed *)
  type x = private 'u x' as 'u
  val f: x -> x x'
end = struct
  type 'a x' = [`A | `B of 'a]
  type x = 'u x' as 'u
  let f a = a
end

Еще один способ сделать это - немного изменить свой тип, сделав приватным только главный конструктор:

(* open *)
type 'a x' = [`A | `B of 'a]
(* closed *)
type x = 'u x' as 'u
(* private *)
type px = private x
let f (a: px) = (a :> x)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...