# Avoiding duplicated definitions in module implementation and interface

**URL:** <https://discuss.ocaml.org/t/avoiding-duplicated-definitions-in-module-implementation-and-interface/1546>\
**Category:** Learning\
**Created:** [February 8, 2018, 1:33pm UTC](https://discuss.ocaml.org/t/avoiding-duplicated-definitions-in-module-implementation-and-interface/1546 "2018-02-08T13:33:52Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![yoriyuki](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/yoriyuki/32/17_2.png) [@yoriyuki](https://discuss.ocaml.org/u/yoriyuki)\
**Post date:** [February 8, 2018, 1:33pm UTC](https://discuss.ocaml.org/t/avoiding-duplicated-definitions-in-module-implementation-and-interface/1546/1 "2018-02-08T13:33:52Z")

</div>

When you need, say, a variant type `t` which is defined in `foo.ml` file as

```auto
type t = A | B | C
...(lots of definitions)...

```

Then, I think you need `foo.mli` like

```auto
type t = A | B | C
...(lots of definitions)...

```

that is, you need to repeat the definition of `t`. If you have a lot of definition it is a pain. Do you know what strategies can be used to solve this problem?

I think this is an old complaint but I forget what is an official solution. I also do not know the recent development of the module syntax so maybe there is a new solution for this? I checked the definition of the module syntax in the manual but can’t find anything related.

---

<div class="post-metadata">

**Author:** ![BikalGurung](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/bikalgurung/32/5105_2.png) [@BikalGurung](https://discuss.ocaml.org/u/BikalGurung)\
**Post date:** [February 8, 2018, 2:22pm UTC](https://discuss.ocaml.org/t/avoiding-duplicated-definitions-in-module-implementation-and-interface/1546/2 "2018-02-08T14:22:25Z")

</div>

One approach is [https://blog.janestreet.com/simple-top-down-development-in-ocaml/](https://blog.janestreet.com/simple-top-down-development-in-ocaml/)

Additionally, if you use dune, the next version (or v1.0?) supports using `.mli` only modules with some caveats, i.e. `.mli` file can only contain `type` definitions.

[Dune mli/rei only modules.](https://github.com/ocaml/dune/pull/489)

---

<div class="post-metadata">

**Author:** ![UnixJunkie](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/unixjunkie/32/638_2.png) [@UnixJunkie](https://discuss.ocaml.org/u/UnixJunkie)\
**Post date:** [February 9, 2018, 12:30am UTC](https://discuss.ocaml.org/t/avoiding-duplicated-definitions-in-module-implementation-and-interface/1546/3 "2018-02-09T00:30:03Z")

</div>

A hackish way would be to use a preprocessor (like Martin Jambon’s cppo).  
You could write once your types in a .mli file, then you #include that file where you need it.

I also very much dislike the duplication of code due to .mli files.

---

<div class="post-metadata">

**Author:** ![lyxia](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/lyxia/32/5208_2.png) [@lyxia](https://discuss.ocaml.org/u/lyxia)\
**Post date:** [February 9, 2018, 1:34pm UTC](https://discuss.ocaml.org/t/avoiding-duplicated-definitions-in-module-implementation-and-interface/1546/4 "2018-02-09T13:34:31Z")

</div>

You can put the public types in their own `.ml` which also acts as the interface, without duplication.

`types.ml`:

```auto
type t = A | B | C

```

Then if you’d like to export the type from the module `Foo`, use `include`

`foo.mli`:

```auto
include module type of Types
...

```

`foo.ml`

```auto
include Types
...

```

---

<div class="post-metadata">

**Author:** ![yoriyuki](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/yoriyuki/32/17_2.png) [@yoriyuki](https://discuss.ocaml.org/u/yoriyuki)\
**Post date:** [February 9, 2018, 1:43pm UTC](https://discuss.ocaml.org/t/avoiding-duplicated-definitions-in-module-implementation-and-interface/1546/5 "2018-02-09T13:43:25Z")

</div>

Thank you. @BikalGurung’s suggestion is also in the same line.

I’m aware of this approach, but it slightly complicates the module and file structures. People expect the `mli` file as a documentation of the `ml` file, so putting important definitions to other module may confuse people.

Since it’s very simple thing, some syntactic sugar for this problem may be worth to have.
