# Why do I need to repeat type declarations between interfaces and implementations (or how do I get around this)?

**URL:** <https://discuss.ocaml.org/t/why-do-i-need-to-repeat-type-declarations-between-interfaces-and-implementations-or-how-do-i-get-around-this/3350>\
**Category:** Learning\
**Created:** [February 16, 2019, 3:31am UTC](https://discuss.ocaml.org/t/why-do-i-need-to-repeat-type-declarations-between-interfaces-and-implementations-or-how-do-i-get-around-this/3350 "2019-02-16T03:31:53Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![mylincode](https://avatars.discourse-cdn.com/v4/letter/m/bc8723/32.png) [@mylincode](https://discuss.ocaml.org/u/mylincode)\
**Post date:** [February 16, 2019, 3:31am UTC](https://discuss.ocaml.org/t/why-do-i-need-to-repeat-type-declarations-between-interfaces-and-implementations-or-how-do-i-get-around-this/3350/1 "2019-02-16T03:31:53Z")

</div>

I’ve just started learning OCaml, and the most pronounced pain point so far has been having to repeat myself between interface and implementation files.

Don’t get me wrong, I think there are _a lot_ of places where it makes sense to separate interface from implementation, and specifically to weaken type-level guarantees made by the interface to give more flexibility for later changes to the implementation. I think the fact that this is inherent in multi-file OCaml programs is for the most part a strength of the language.

By the same token, there are cases where it would really make sense to carry definitions made in the interface file over to the implementation file. Say I have the interface file `my_data_structure.mli`, and it looks something like this:

```auto
module type ELEMENT = sig
  type t
  ...
end

module type HYPERPARAMETERS = sig
  val foo: bar
  ...
end

module Create (Element: ELEMENT) (Hyperparameters: HYPERPARAMETERS) : sig
  type element = Element.t
  ...
end

```

And now say I have to write `my_data_structure.ml`. I’m going to have to duplicate the definitions of `ELEMENT` and `HYPERPARAMETERS`, and as far as I can tell there is little to no reason I’d want either to have a different definition within the implementation file. The same goes for the guarantee inside `Create` that `type element = Element.t`: I’m going to have to repeat that declaration and guarantee inside my implementation.

I’ve found a few workarounds so far, such as this [`include` hack](https://blog.janestreet.com/simple-top-down-development-in-ocaml/), and my preferred so far is to extract `ELEMENT` and `HYPERPARAMETERS` into their own interface-only module(s). And this certainly works, but it still feels over-complicated and inelegant.

So this leaves me with two questions:

- Is there a better workaround I’ve yet to stumble upon? Is there some idiom I’m unaware of that the community has centered around for solving just this sort of problem?

- From a design standpoint, what’s the reasoning behind this behavior of the language? It seems to me that, in any place where a type declaration / definition that is present in the interface file is missing from the implementation file, the compiler could simply substitute the interface as a “default”, and otherwise allow what’s in the implementation file to be a local override (provided it’s compatible with the interface). Is there something I’m not considering that makes this infeasible / undesired, or is this just not something anyone’s gotten around to implementing?

---

<div class="post-metadata">

**Author:** ![yawaramin](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/yawaramin/32/3384_2.png) [@yawaramin](https://discuss.ocaml.org/u/yawaramin)\
**Post date:** [February 16, 2019, 3:49am UTC](https://discuss.ocaml.org/t/why-do-i-need-to-repeat-type-declarations-between-interfaces-and-implementations-or-how-do-i-get-around-this/3350/2 "2019-02-16T03:49:58Z")

</div>

Yeah people keep hitting this:

- [https://stackoverflow.com/q/22348341/20371](https://stackoverflow.com/q/22348341/20371)
- [https://stackoverflow.com/q/3238509/20371](https://stackoverflow.com/q/3238509/20371)
- [Avoiding duplicated definitions in module implementation and interface](https://discuss.ocaml.org/t/avoiding-duplicated-definitions-in-module-implementation-and-interface/1546)

There are a couple of tricks you can use to work around it in some situatuons.You already discovered the ‘top-down development’ trick, there’s also a ‘recursive modules’ trick which works for modules that contain only type definitions (and also external definitions): [https://blog.janestreet.com/a-trick-recursive-modules-from-recursive-signatures/](https://blog.janestreet.com/a-trick-recursive-modules-from-recursive-signatures/) . This one actually also works with a single module.

---

<div class="post-metadata">

**Author:** ![jonathandoyle](https://avatars.discourse-cdn.com/v4/letter/j/a3d4f5/32.png) [@jonathandoyle](https://discuss.ocaml.org/u/jonathandoyle)\
**Post date:** [February 16, 2019, 2:53pm UTC](https://discuss.ocaml.org/t/why-do-i-need-to-repeat-type-declarations-between-interfaces-and-implementations-or-how-do-i-get-around-this/3350/3 "2019-02-16T14:53:38Z")

</div>

See also

> [@What is the reason of separation of module implementation and signatures in OCaml?](https://discuss.ocaml.org/t/what-is-the-reason-of-separation-of-module-implementation-and-signatures-in-ocaml/1735):
>
> What is the reason of the separation of module implementation and signatures? Wouldn’t it be better to describe signatures in function definitions? For example: let sum a:int b:int = a + b instead of: (\* \*.mli \*) val sum : int -\> int -\> int (\* \*.ml \*) let sum a b = a + b

---

<div class="post-metadata">

**Author:** ![perry](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/perry/32/518_2.png) [@perry](https://discuss.ocaml.org/u/perry)\
**Post date:** [February 16, 2019, 4:00pm UTC](https://discuss.ocaml.org/t/why-do-i-need-to-repeat-type-declarations-between-interfaces-and-implementations-or-how-do-i-get-around-this/3350/4 "2019-02-16T16:00:34Z")

</div>

I am not bothered by the need to create the explicit interface file, but then again, I loved using Modula-2 back in the day.

My usual trick to avoid typing too much is to use the compiler itself to generate the first draft of the `.mli` file; if you use `ocamlc` with the `-i` flag, it will dump out the definitions of the values in a given `.ml` file; you just edit a bit (and remove what isn’t part of the explicit interface) and you’re set.

All this said, every once in a great while I find myself having a problem where something is _generating_ code and I need to have different text in the interface and the implementation. I believe the last time this happened I was playing with Menhir and wanted the generated token type for use in the lexer to get cleaned up a bit. I believe I used a combination of `cppo` and some other tools to achieve what I wanted.

---

<div class="post-metadata">

**Author:** ![mylincode](https://avatars.discourse-cdn.com/v4/letter/m/bc8723/32.png) [@mylincode](https://discuss.ocaml.org/u/mylincode)\
**Post date:** [February 16, 2019, 5:47pm UTC](https://discuss.ocaml.org/t/why-do-i-need-to-repeat-type-declarations-between-interfaces-and-implementations-or-how-do-i-get-around-this/3350/5 "2019-02-16T17:47:30Z")

</div>

I’m very much behind requiring everything specified in the implementation file to be repeated in the interface; it’s just not clear to me why the opposite is also required.

If I write `type foo = ...` in the implementation file, it’s not clear that I intended `foo` to be visible outside of the implementation, and so it makes sense that I need to mention something about it in the interface file.

But say now I give a `type foo = ...` definition in the interface file. It’s _possible_ for me to give a different definition of `foo` in the implementation (provided type compatibility rules are respected), but if I give no definition, **my program is guaranteed invalid**. From the admittedly small set of OCaml programs I’ve written so far, in any case where I expose a `type` or `module type` in a signature, I have no intention of specifying that type any differently in the implementation.

Obviously that option to do so should remain open, but I don’t understand why the compiler cannot use `type` definitions given in an interface as defaults when they are not also given in an implementation. Or if that’s too much, having a syntax like `type foo = default` that can be used in the implementation would go a long way towards staying DRY.

---

<div class="post-metadata">

**Author:** ![RogerT](https://avatars.discourse-cdn.com/v4/letter/r/5f8ce5/32.png) [@RogerT](https://discuss.ocaml.org/u/RogerT)\
**Post date:** [February 16, 2019, 8:36pm UTC](https://discuss.ocaml.org/t/why-do-i-need-to-repeat-type-declarations-between-interfaces-and-implementations-or-how-do-i-get-around-this/3350/6 "2019-02-16T20:36:29Z")

</div>

OUsing the expression `type foo = ...` seems to hide you the problem.

AFAIK, you should respect the best practice of using an abstract type (already discussed in this website) as follows:

```
(* foo.ml *)
module type FOO = 
sig
type t
val bar : t -> int (* or anything you want *)
end

module Foo:FOO =
struct
type t = int list (* or anything else that makes sense *)
let bar = (* todo *)
end

```

This way, you can improve the structure with another better type without impacting the user of your module if he respects your module signature.  
The contrary would create a strong and painful dependency, and he would be forced to update his program every time you change the structure of your module (if the signature of your module and the structure share the same concrete type).

---

<div class="post-metadata">

**Author:** ![mylincode](https://avatars.discourse-cdn.com/v4/letter/m/bc8723/32.png) [@mylincode](https://discuss.ocaml.org/u/mylincode)\
**Post date:** [February 16, 2019, 9:03pm UTC](https://discuss.ocaml.org/t/why-do-i-need-to-repeat-type-declarations-between-interfaces-and-implementations-or-how-do-i-get-around-this/3350/7 "2019-02-16T21:03:11Z")

</div>

I’m not disputing that abstract types are highly useful (and that there are many places where choosing them is the right answer). But there are other places (e.g. module types that are accepted by functors exposed as part of the API, or variants which you consciously decide expose as part of your API) where having to repeat yourself just seems needless.

I can also understand having the language be “idiot-proof” and guide people towards best practices, but take my hypothetical `type t = default` opt-in syntax. Something like that would still require the programmer to consciously decide, “yes, I want my interface to match my implementation for this type”, and someone would likely not learn of such a feature until they explicitly sook out how to do such a thing concisely.

I’ll also say that I don’t think @RogerT’s example is actually a counterexample to my point. To emphasize, I’m only asking why type definitions from the interface aren’t copied into the implementation, and not the other way around. In a hypothetical world where OCaml worked the way I wanted, if you had already written the implementation of `type t`, you would still need to separately specify its interface, and there decide that it should be left abstract. Everything put into the interface would still have to be put there manually and deliberately, and I think that that alone should be sufficient for guiding users of the language towards these best practices.

# Edit

I should clarify that when I previously said

> [@mylincode](#):
>
> From the admittedly small set of OCaml programs I’ve written so far, in any case where I expose a `type` or `module type` in a signature, I have no intention of specifying that type any differently in the implementation.

I only meant that when I write `type t = ...` in the interface, I’ve yet to find a case where I wanted a different definition in the implementation. I’ve definitely used abstract types and agree with their value, but perhaps it sounded like I didn’t, and that’s what @RogerT was trying to get at.

---

<div class="post-metadata">

**Author:** ![RogerT](https://avatars.discourse-cdn.com/v4/letter/r/5f8ce5/32.png) [@RogerT](https://discuss.ocaml.org/u/RogerT)\
**Post date:** [February 16, 2019, 10:01pm UTC](https://discuss.ocaml.org/t/why-do-i-need-to-repeat-type-declarations-between-interfaces-and-implementations-or-how-do-i-get-around-this/3350/8 "2019-02-16T22:01:58Z")

</div>

> [@mylincode](#):
>
> I’m only asking why type definitions from the interface aren’t copied into the implementation, and not the other way around.

Let me try to answer this way:

Type definitions in a signature can be abstract or concrete. You already know the pros and cons, especially for the user of the module.

Type definitions in a structure must be concrete (e.g. `type abc = int * string * string list`) because you need that to write concrete functions that use that concrete type.  
I’m not aware of another way that may exist to use abstract type `type t` in a structure - OCaml experts will comment that if necessary.

You can copy type definitions from the structure (aka implementation) to the signature (aka interface). Manually or with the compiler to save time: `ocamlc -i` (then let types concrete or make them abstract).

You can write a module or a set of modules (i.e. a program) without writing any signature. It’s ok if it type checks. It’s usually the way one learns OCaml because it’s enough effort and adding signature may add confusion.

What may disturb you is that there are many ways to write an OCaml program.

Depending on your goal and requirements, you may find easier to start with writing the signature of all your modules because you know exactly what you want. Or you may want to start with playing a little bit with the implementation of some functions to clarify what the signatures should be (val, type, exception).  
Or you may feel more comfortable with writing directly your module structures, and at the end decide if you need a signature and what signature will meet your requirements.

OCaml offers you these degrees of freedom.  
So, each programmer can choose his way.

---

<div class="post-metadata">

**Author:** ![yawaramin](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/yawaramin/32/3384_2.png) [@yawaramin](https://discuss.ocaml.org/u/yawaramin)\
**Post date:** [February 16, 2019, 10:31pm UTC](https://discuss.ocaml.org/t/why-do-i-need-to-repeat-type-declarations-between-interfaces-and-implementations-or-how-do-i-get-around-this/3350/9 "2019-02-16T22:31:44Z")

</div>

> [@mylincode](#):
>
> I’m only asking why type definitions from the interface aren’t copied into the implementation, and not the other way around.

I think in the general case there’s no way to guarantee that you’d do it correctly. For example, you could have a [private type abbreviation](https://caml.inria.fr/pub/docs/manual-ocaml/extn.html#sec239)–this lets you wrap old types in new types without allocation and let users conveniently convert from the new type to the old type (one-way only). You would write `type new_type = private old_type` in the interface but actually define it as `type new_type = old_type` in the implementation.

So you could introduce a special rule for when you see private types that they must be copied from the interface to the implementation but just without the `private` access modifier. But what if in some case you _actually wanted_ to keep the `private` modifier? Strictly speaking, it’s allowed by OCaml, but a type-copy rule would introduce a special case where it won’t be. I think this kind of special casing is what the language implementors try to avoid.

---

<div class="post-metadata">

**Author:** ![RogerT](https://avatars.discourse-cdn.com/v4/letter/r/5f8ce5/32.png) [@RogerT](https://discuss.ocaml.org/u/RogerT)\
**Post date:** [February 16, 2019, 10:33pm UTC](https://discuss.ocaml.org/t/why-do-i-need-to-repeat-type-declarations-between-interfaces-and-implementations-or-how-do-i-get-around-this/3350/10 "2019-02-16T22:33:31Z")

</div>

Quick Edit:  
This document may be useful to understand the OCaml module system:  
[https://www.di.ens.fr/~zappa/teaching/stt05/ocaml\_modules.pdf](https://www.di.ens.fr/~zappa/teaching/stt05/ocaml_modules.pdf)  
See page 11 Multiple views of the same module.

---

<div class="post-metadata">

**Author:** ![lpw25](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/lpw25/32/144_2.png) [@lpw25](https://discuss.ocaml.org/u/lpw25)\
**Post date:** [February 17, 2019, 9:25pm UTC](https://discuss.ocaml.org/t/why-do-i-need-to-repeat-type-declarations-between-interfaces-and-implementations-or-how-do-i-get-around-this/3350/11 "2019-02-17T21:25:33Z")

</div>

> I’m only asking why type definitions from the interface aren’t copied into the implementation, and not the other way around.

I think that doing this properly in the general case requires at least higher-order unification. So it’s probably possible but it is not easy. There are some similar requirements for implementing modular implicits so I’m hoping that we can have at look at doing this as part of that work.

---

<div class="post-metadata">

**Author:** ![paurkedal](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/paurkedal/32/586_2.png) [@paurkedal](https://discuss.ocaml.org/u/paurkedal)\
**Post date:** [February 18, 2019, 6:55pm UTC](https://discuss.ocaml.org/t/why-do-i-need-to-repeat-type-declarations-between-interfaces-and-implementations-or-how-do-i-get-around-this/3350/12 "2019-02-18T18:55:02Z")

</div>

For cases where literal inclusion suffice, [`ppx_import`](https://github.com/ocaml-ppx/ppx_import) announces in it’s README that “It is also possible to import items from your own .mli file.” I haven’t tried it yet.
