OCaml эквивалентные типы - PullRequest
       7

OCaml эквивалентные типы

6 голосов
/ 15 февраля 2012

Я строю две библиотеки в OCaml, которые содержат один и тот же тип варианта.Детали этого варианта не слишком важны, кроме того, что он действительно большой, и было бы неудобно писать для него функции преобразования вручную.(На самом деле это перечисление bfd_architecture, преобразованное из C с помощью ocamlidl).

Сейчас я пишу программу с использованием двух библиотек.В частности, я вызываю Af, которая возвращает значение A.variant_type, и мне нужно использовать это значение в вызове Bg, который принимает значение B.variant_type в качестве ввода.

Есть лиЛюбой способ сказать OCaml, что A.variant_type и B.variant_type действительно одного типа, и, таким образом, можно преобразовать значение из одного в другое?Библиотеки независимы, поэтому они не должны ссылаться друг на друга.Прямо сейчас я использую Obj.magic, чтобы сделать преобразование, но это хак.

Ответы [ 3 ]

8 голосов
/ 15 февраля 2012

Я полагаю, что нет чистого пути, если только эти библиотеки не имеют какой-либо общей зависимости, которая определяет этот тип (т. Е. Один и тот же модуль, на который ссылаются обе библиотеки во время сборки).

3 голосов
/ 16 февраля 2012

Если вы действительно хотите, чтобы тип варианта появился в обеих библиотеках, вы также можете принудительно проверить, что они эквивалентны. Во второй библиотеке вы можете написать:

type t = OtherLib.t = | A | B | C | ...

Это заставит компилятор проверить, что OtherLib.t = A | Б | C | ... и сделать два типа равными. Я не думаю, что это действительно решает ваш случай, так как вы, вероятно, не хотите менять ни одну из библиотек.

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

1 голос
/ 15 февраля 2012

Вам не нужно использовать Obj.magic, хотя вы должны использовать некоторое"волшебство",

external convertAB : A.t -> B.t = "%identity"
external convertBA : B.t -> A.t = "%identity"

достаточно для преобразования.Конечно, я понимаю вашу озабоченность;оба типа должны быть одинаковыми, иначе вы будете иметь дело с ошибками во время выполнения.Если это вообще возможно и уместно, преобразование этих вариантов в Полиморфные варианты решит проблему.

...