Проблема композиционного дизайна в OCaml - PullRequest
0 голосов
/ 08 ноября 2019

Я работаю над решателем ограничений в 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
...