I want to make a functor, which only needs a single function implementation as its argument.
My problem is, that I don’t want to have to provide the input type of the function in the first-class module (as its type is quite complex and always the same).
Sorry, if the terminology I am using is incorrect
I hope you can understand me anyways.
Is there a way the following simplified example can work?
Basically the 'a should be replaced by the type t which is declared inside Make.
module type S = sig
val to_string : 'a -> string
end
module Make (Impl : S) = struct
type t = int
let to_string : t -> string = Impl.to_string
end
module MyModule = Make (struct
let to_string = string_of_int
end)
Perhaps you can just define the type outside the functor argument ?
type large_type = ...
module MyModule1 = Make (struct type t = large_type let to_string = ... end)
module MyModule2 = Make (struct type t = large_type let to_string = ... end)
(* etc *)
Writing the type is probably the simplest solution.
However, it is possible to use first-class modules to lift an inferred type to the module level:
module type S = sig
type t
val to_string: t -> string
end
let make (type a) f : (module S with type t =a) =
(module struct
type t = a
let to_string = f
end)
module R = (val (make Fun.id))
I use this pattern from time to time when I encode some computation in types with GADTs and want to extract the result of the computation at the module level.
For more info on this technique see the similar example in Real World OCaml: First-Class Modules - Real World OCaml (in the subsection More on Locally Abstract Types).