Я работаю над решателем ограничений в OCaml, и мне нужна помощь в решении проблемы проектирования (это относится к OCaml, а не к решателю ограничений как таковым).
У меня есть коллекциямодулей M1
, M2
, ..., Mn
и модулей, объединяющих их, таких как P1(M1, M2)
, P2(M2, M3)
. Все они имеют общую подпись, назовите ее I
, но комбинаторам Pi(M1,M2,...)
могут потребоваться модули M1, M2, ...
для реализации расширенной подписи I
, что является специальным требованием Pi
.
Кроме того, мы видим, что модули P1
и P2
параметризованы общим модулем M2
, и в нашем случае это также означает, что они должны работать с одним и тем же значением M2.t
. Следовательно, императивная идея заключается в том, чтобы полагаться на M2.t ref
внутри P1
и P2
. Поскольку я использую эти модули в алгоритме обратного отслеживания, использование ссылок усложняет все.
Одним из способов может быть изменение интерфейса P1
и P2
для передачи M2.t
в качестве параметра, нотогда подпись I
больше не будет уважаться.
Я думал о том, чтобы иметь список всех модулей и обойти весь список (см. ниже то, что я имею в виду под «списком модулей»),но это нарушает требования, согласно которым P1(M1,M2)
требуется расширенная подпись над M1
или M2
, поскольку тип стирается в I
. Решение состоит в том, чтобы иметь "супер сигнатуру" I
, охватывающую все необходимые функции всех Pi
, но не все функции, запрашиваемые Pi
, имеют смысл для всех модулей ... и это несколько нарушает расширяемость.
Чтобы сделать вещи, возможно, еще более сложными, у меня есть сотни модулей (по экземплярам функторов).
Я думаю, что я просто пойду с "эталонным дизайном", но я выложу это на случай, если кто-тосталкивался с подобной проблемой раньше или у вас есть идеи по использованию темных (или нет) функций OCaml для решения этой проблемы.
Спасибо!
Приложение: Список модулей
module type List_combinator =
sig
type t
(....)
end
module List_atom(A: I) :
sig
type t = A.t
include List_combinator with type t := t
end
module List_cons(A: I)(B: List_combinator) :
sig
type t = (A.t * B.t)
include List_combinator with type t := t
end