In my codebase I have a few modules that are parametric on a monad. Some of them are also functors, and receive other parameters that are parametric on this monad, and all arguments must match.
I see two solutions to enforce that.
First solution:
module type Param = sig
module MyMonad
...
end
module F
(M: MyMonad)
(P: Param with module MyMonad = MyMonad) =
struct ... end
Second solution:
module Param (M: MyMonad) = struct
module type S = sig ... end
end
module F
(M: MyMonad)
(P: Param(MyMonad).S) =
struct ... end
I prefer the second one, it’s easier to instantiate.
But 1) is this some footgun I can’t see coming and 2) is there a more idiomatic way of doing this?