# Functors and type abstraction

**URL:** <https://discuss.ocaml.org/t/functors-and-type-abstraction/6214>\
**Category:** Learning\
**Created:** [August 8, 2020, 12:32pm UTC](https://discuss.ocaml.org/t/functors-and-type-abstraction/6214 "2020-08-08T12:32:18Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Paroxysmisch](https://avatars.discourse-cdn.com/v4/letter/p/c77e96/32.png) [@Paroxysmisch](https://discuss.ocaml.org/u/Paroxysmisch)\
**Post date:** [August 8, 2020, 12:32pm UTC](https://discuss.ocaml.org/t/functors-and-type-abstraction/6214/1 "2020-08-08T12:32:18Z")

</div>

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*)

end
;;

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
end
;;

```

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.

Thanks.

---

<div class="post-metadata">

**Author:** ![Levi\_Roth](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/levi_roth/32/2268_2.png) [@Levi\_Roth](https://discuss.ocaml.org/u/Levi_Roth)\
**Post date:** [August 8, 2020, 1:32pm UTC](https://discuss.ocaml.org/t/functors-and-type-abstraction/6214/2 "2020-08-08T13:32:59Z")

</div>

> [@Paroxysmisch](#):
>
> 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?

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.

---

<div class="post-metadata">

**Author:** ![giltho](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/giltho/32/3521_2.png) [@giltho](https://discuss.ocaml.org/u/giltho)\
**Post date:** [August 8, 2020, 2:09pm UTC](https://discuss.ocaml.org/t/functors-and-type-abstraction/6214/3 "2020-08-08T14:09:32Z")

</div>

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

Try

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

```

Note the `:=` instead of `=` 🙂

---

<div class="post-metadata">

**Author:** ![Paroxysmisch](https://avatars.discourse-cdn.com/v4/letter/p/c77e96/32.png) [@Paroxysmisch](https://discuss.ocaml.org/u/Paroxysmisch)\
**Post date:** [August 8, 2020, 7:04pm UTC](https://discuss.ocaml.org/t/functors-and-type-abstraction/6214/4 "2020-08-08T19:04:17Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![silene](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/silene/32/2707_2.png) [@silene](https://discuss.ocaml.org/u/silene)\
**Post date:** [August 9, 2020, 8:56am UTC](https://discuss.ocaml.org/t/functors-and-type-abstraction/6214/5 "2020-08-09T08:56:32Z")

</div>

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.
