Reputation: 605
I have a problem with interlocked modules: I want to refer to a type defined in the first module.
module type E = sig
type event
end
type ev = Ev;;
module EE : E = struct type event = ev end;;
module type StateType = functor (E : E ) -> sig
type event = E.event
type state_t = {
mutable event_success : event option;
}
val set_event_success : state_t -> event option -> unit
val create : unit -> state_t
end
module State : StateType = functor (E : E) -> struct
type event = E.event
type state_t = {
mutable event_success : event option;
}
let create () = {
event_success = None;
}
let set_event_success s e = (s.event_success <- e;)
end
module S = State(struct type event = ev end);;
let s = S.create ();;
S.set_event_success s (Some(Ev));;
\- : unit = ()
So, it works.
module type AgentType =
functor (S: StateType) -> functor (E : E) ->
sig
type event = E.event
type state_t = S.state_t
end
I get this error:
Error: Unbound type constructor S.state_t
I don't understand why I get this error, since S is clearly set with the module StateType
.
My goal is to do the following declaration:
module Ag = Agent ( State(struct type event = ev end)) (struct type event = ev end)
How can I do that?
Upvotes: 1
Views: 7884
Reputation: 6379
That's because StateType
is the type of a functor, not a module.
You should declare StateType
as
module type StateType =
sig
type event
type state_t = {
mutable event_success : event option;
}
val set_event_success : state_t -> event option -> unit
val create : unit -> state_t
end
and the functor State
as
module State (E : E) : (StateType with type event = E.event) =
struct
type event = E.event
type state_t = {
mutable event_success : event option;
}
let create () = {
event_success = None;
}
let set_event_success s e = (s.event_success <- e;)
end
How to solve this kind of problems:
Don't write functor types.
Instead write the signature of the output module and use with type
to add type equations.
For Agent
, the output signature would be be
module type AgentType =
sig
type event
type state_t
end
and the Agent
functor would look like
module Agent (S : StateType) (E : E) : (AgentType with type event = E.event and type state_t = S.state_t) = …
Upvotes: 3