Это классическая проблема дизайна.В языках ООП это сложно решить элегантно, потому что класс инкапсулирует как определение типа, так и методы, связанные с этим типом.Таким образом, как только у вас есть такая функция, как a_of_b, которая в равной степени относится к двум типам, для нее нет ясного места.
OCaml правильно предоставляет различные языковые механизмы для этих различных потребностей: определения типоввведен с ключевым словом type
, а связанные методы собраны в module
.Это дает вам большую гибкость при разработке вашего API, но не решает проблему автоматически.
Одна возможность - определить модули A и B, как с их соответствующими типами, так и функциями сравнения.Тогда остается вопрос, куда поставить a_of_b
и b_of_a
.Вы можете произвольно отдать предпочтение модулю A и определить функции A.to_b
и A.of_b
.Это то, что стандартная библиотека сделала, когда она поместила to_list
и of_list
в массив.Этому не хватает симметрии;нет причины не помещать эти функции вместо B.
Вместо этого вы можете стандартизировать использование of_
функций против to_
функций.Допустим, вы предпочитаете to_
.Тогда вы бы определили функции A.to_b
и B.to_a
.Теперь проблема в том, что модули A и B взаимозависимы, что возможно, только если вы определите их в одном файле.
Если у вас будет много функций, которые работают со значениями типа A.t
и B.t
, тогда, возможно, стоит определить модуль AB и поместить все эти функции в него.Если вам понадобится только два, то дополнительный модуль, возможно, излишний.
С другой стороны, если общее количество функций относительно A и B невелико, вы можете создать только модуль AB с * 1026.*, type b
и все связанные методы.Однако это не следует соглашению сообщества OCaml о присвоении типа t
в его собственном модуле, и будет сложнее применять функторы Set и Map к этим типам.