Functors and type abstraction

I have a quick question regarding type abstraction when dealing with functors. Why is it that we have to repeat ‘endpoint = Endpoint.t’ in the following example (taken from the real world ocaml book)? I understand the use of the ‘with type’, but once we have written it, why is it also necessary to say ‘type endpoint = Endpoint.t’ in the struct body? Is it only to satisfy the fact that we have declared a ‘type endpoint’ in the ‘Interval_intf’ which then must be satisfied by the functor?

    module Make_interval(Endpoint : Comparable)
  : (Interval_intf with type endpoint = Endpoint.t)
= struct

  type endpoint = Endpoint.t     (* Why is this necessary? *)
  type t = | Interval of Endpoint.t * Endpoint.t
           | Empty

  (* Skipping the rest of the implementation*)


module type Interval_intf = sig
  type t
  type endpoint
  val create : endpoint -> endpoint -> t
  val is_empty : t -> bool
  val contains : t -> endpoint -> bool
  val intersect : t -> t -> t

I had a look at the reference manual, but I still can’t understand. I know that destructive substitution gets rid of this duplication, but I just wanted to know exactly why the duplication is necessary.


Sounds right to me. I think this is just the same phenomenon as you see with interfaces and implementations in general. For example, if you include a type in a .mli file you still have to include it in the .ml file.

1 Like

Not 100% sure, because I don’t have a computer to test right now but you should not need it, although you need to tell the compiler why


: (Interval_intf with type endpoint := Endpoint.t)

Note the := instead of = :slight_smile:

1 Like

Yup, := works. I wonder what the point of = is, if it just clutters up the interface :thinking:.

That is not quite the same. The := substitution is destructive, which means that the resulting signature no longer contains an endpoint type. (That is why the definition type endpoint = ... can later be skipped from the implementation without error.) Thus, the resulting module no longer satisfies the Interval_intf signature, which might not have been the original intent.