Функторы с несколькими аргументами в OCaml - PullRequest
14 голосов
/ 21 августа 2010

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

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

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

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

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

1 Ответ

19 голосов
/ 21 августа 2010

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

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 ….

...