Функторы с несколькими аргументами в OCaml

У меня есть следующая ситуация:

module type M = sig type s = ...  end

module Make(P: Something) : (M with type s = P.t) = struct
   type s = P.t
   ...
end

который отлично работает для создания модулей типа M, которые используют конкретную реализацию модулей типа Something внутри своей реализации.

Теперь предположим, что у меня есть другой модуль, определенный как

module type AU = sig
  val feed : float -> unitv
  val nth : int -> (float -> float)
  val reset : unit -> unit
end

который имеет различные реализации

module SUAlg : AU = struct ... end
module MLAlg : AU = struct ... end
module ACEAlg : AU = struct ... end

Точка вопроса заключается в том, что модуль M должен быть параметризован поверх двух вещей: модуль Something и модуль AU, чтобы он что-то вроде

module Make(P: Something) : (M with type s = P.t) = struct
   type s = P.t
   module Alg = MLAlg (* just an example *)
   ...
end

но я хотел бы иметь общий функтор, заданный a Something и заданный AU, он создает модуль с обеими конкретизированными вещами. Есть ли способ получить это легко?

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

Заранее спасибо

Ответ 1

Да, функтор может иметь несколько аргументов. Синтаксис выглядит следующим образом:

module Make_LOffset
            (V:Lattice_With_Isotropy.S)
            (LOffset : Offsetmap.S with type y = V.t and type widen_hint = V.widen_hint) =
struct
   …
end

Затем функтор можно применить с помощью Make_LOffset(V)(LOffset).

В этом примере, взятом из существующего кода, чтобы убедиться, что он синтаксически корректен, Make_LOffset параметризуется двумя модулями V и LOffset соответствующих сигнатур Lattice_With_Isotropy.S и Offsetmap.S. Существуют дополнительные ограничения типа между двумя сигнатурами, часть with type … and type ….