I have read many posts here about modules but the following still isn’t clear to me. If Foo
is a module of type FOO
, and BAR
is a module type for a functor that accepts some Foo:FOO
and defines something else, how can I get the “something else”? In other words how do I say that some module Bar
has type BAR Foo
? In code:
module type FOO =
sig
type t
val x : t
end
module type BAR =
functor (Foo:FOO) ->
sig
val y : Foo.t
end
module Foo : FOO =
struct
type t = bool
let x = true
end
(** Doesn't work *)
module Bar : BAR Foo =
struct
let y = Foo.x
end
(** Doesn't work *)
module type BAR_At_Foo = BAR (Foo)
How can I, or why can’t I, do this?
My understanding of the module system is such that I think this is completely reasonable and doesn’t pose any problems whatsoever–it is approximately like instantiating a dependent product type at a particular value, all of which is known at compile time. So please disabuse me of this idea if I’m being naïve.
In anticipation of questions: My use case is that Foo
is some configuration module that defines some types and Bar:BAR
is a module that provides functionality whose types depend on the types from Foo
. My library accepts a Foo:FOO
and Bar:BAR(Foo)
and returns something very complicated. I am aware that I could merge Foo
and Bar
into one massive module, or better yet a record, but I’m very interested in understanding this from a dependent types perspective.
(I hope the answer is not that I’ve encoded some obvious undecidability that I’m blindly overlooking.)