Search code examples
modulecompiler-errorsincludeocamlfunctor

How does include work?


I have

module type T = sig
    type t
end

and

module Make (TypeProvider : T) = struct
    include TypeProvider
    type d = Wrapped of t
end

and

module Test = struct
    include Make (struct type t = ForWrap end)
    let f = function | Wrapped ForWrap -> ()
end

I imagined Test after compilation like

module Test = struct
    type t = ForWrap
    type d = Wrapped of t
    let f = function | Wrapped ForWrap -> ()
end

But in real, it is not compilable code. OCaml says me:

module Test = struct
    include Make (struct type t = ForWrap end)
    let f = function | Wrapped ForWrap -> ()
                               ^^^^^^^

Error: Unbound constructor ForWrap

end

And I cannot understand why. What's the problem in my solution?


Solution

  • Let's see the signature of Make (struct type t = ForWrapp end):

    module M = Make(struct type t = ForWrapp end)
    

    ocamlc -c -i xxx.ml shows you the signature of this module:

    module M : sig 
      type t
      type d = Wrrapped of t
    end
    

    Note that the constructor ForWrapp is not available in the result module. This is why your code does not type-check.

    Why the constructor is gone? This is since the functor Make's argument signature is T. T defines a type t which is abstract. Even if you apply Make to a module with more detailed signature (here struct type t = ForWrapp end) it is coerced down to T and the constructor information is lost.