Domanda

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?

È stato utile?

Soluzione

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) = …
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top