Self-referential first-class modules in functor signature

How can I have a module signature where one of the values accepts a first-class module of that very same signature? MWE:

module type SIG = sig
	type t
	val size : int
	val convert : (module SIG) -> t -> P.t option
end

module Make (Params : sig val size : int end) : SIG = struct
	type t = int
	include Params
	let convert (module P : SIG) x = Some x
end

Let’s say Make(struct let size = foo end) is supposed to represent positive integers smaller than size, and I want a convert function to convert P.t and Q.t where P and Q are different instances of this same functor (with possibly different sizes). Is this possible to express in OCaml?

1 Like

I would love to know a real situation where this would be useful, but yes:

module rec M : sig
  module type SIG = sig
    type t
    val size : int
    val of_int : int -> t option
    val convert : (module M.SIG with type t = 'a) -> t -> 'a option
  end
end = M

module Make (Params : sig val size : int end) : M.SIG = struct
  type t = int

  include Params

  let of_int v = if v > size then None else Some v

  let convert (type a) (module P : M.SIG with type t = a) t =
    P.of_int t
end