# Using a Set in a module type

**URL:** <https://discuss.ocaml.org/t/using-a-set-in-a-module-type/737>\
**Category:** Learning\
**Tags:** module\
**Created:** [August 19, 2017, 6:28am UTC](https://discuss.ocaml.org/t/using-a-set-in-a-module-type/737 "2017-08-19T06:28:23Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![coventry](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/coventry/32/1093_2.png) [@coventry](https://discuss.ocaml.org/u/coventry)\
**Post date:** [August 19, 2017, 6:28am UTC](https://discuss.ocaml.org/t/using-a-set-in-a-module-type/737/1 "2017-08-19T06:28:23Z")

</div>

Suppose I have a module `module Bounded(E: Set.OrderedType)`, and I want to use  
`Set.Make(E)` as a component of Bounded.t, like

```auto
type t = { mutable data : Set.Make(struct
    type t = E.t let compare = compare end); };

```

Is there a way to do that?

---

<div class="post-metadata">

**Author:** ![gsg](https://avatars.discourse-cdn.com/v4/letter/g/858c86/32.png) [@gsg](https://discuss.ocaml.org/u/gsg)\
**Post date:** [August 19, 2017, 8:12am UTC](https://discuss.ocaml.org/t/using-a-set-in-a-module-type/737/2 "2017-08-19T08:12:00Z")

</div>

Directly, no: the way to do this is to name a module that is the result of the functor application. Like this:

```
module ESet = Set.Make (E)

type t = {
  mutable data : ESet.t;
}

```

And if you need to write the signature of that module:

```
module ESet : Set.S with type elt = E.t

type t = {
  mutable data : ESet.t;
}

```

Note that functor application is side effecting and allowing it in type definitions would cause all kinds of problems.

---

<div class="post-metadata">

**Author:** ![coventry](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/coventry/32/1093_2.png) [@coventry](https://discuss.ocaml.org/u/coventry)\
**Post date:** [August 19, 2017, 8:25am UTC](https://discuss.ocaml.org/t/using-a-set-in-a-module-type/737/3 "2017-08-19T08:25:52Z")

</div>

Thanks, @gsg. I was a bit unclear. My problem is creating `ESet` within another functor. E.g., I would like to do something like this, but syntactically valid:

```auto
module Bounded(E: Set.OrderedType) = struct

  let module SE = Set.Make(struct
      type t = E.t let compare = E.compare end)

  type t = {
    bound : int ;
    mutable data : SE.t;
  }
...

```

---

<div class="post-metadata">

**Author:** ![gsg](https://avatars.discourse-cdn.com/v4/letter/g/858c86/32.png) [@gsg](https://discuss.ocaml.org/u/gsg)\
**Post date:** [August 19, 2017, 9:17am UTC](https://discuss.ocaml.org/t/using-a-set-in-a-module-type/737/4 "2017-08-19T09:17:07Z")

</div>

It’s very much the same for functors:

```
module Bounded (E: Set.OrderedType) = struct
  module SE = Set.Make (E)

  type t = {
    bound : int ;
    mutable data : SE.t;
  }
end

```

A few things to note: `let module M = ...` is the syntax for _local_ binding of modules. `module M = ...` defines an element within the current module, which is what you want here.

You can just pass `E` to `Set.Make` because module type checking is structural: if `E` has fields of the right names with the right types, it will be accepted. (They can be out of order, there can be other fields, etc - all of that will be ignored.)

---

<div class="post-metadata">

**Author:** ![octachron](https://avatars.discourse-cdn.com/v4/letter/o/49beb7/32.png) [@octachron](https://discuss.ocaml.org/u/octachron)\
**Post date:** [August 19, 2017, 10:06am UTC](https://discuss.ocaml.org/t/using-a-set-in-a-module-type/737/5 "2017-08-19T10:06:15Z")

</div>

> [@gsg](#):
>
> Directly, no: the way to do this is to name a module that is the result of the functor application.

To be pedant, it is in fact possible to access type components of a functor application inside a type definition. For instance,

```
type t = { x : Set.Make(String).t }

```

is valid. It is indeed generally better to name the result of the functor application before using it, but this is not always easy when recursive modules are involved.

---

<div class="post-metadata">

**Author:** ![coventry](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/coventry/32/1093_2.png) [@coventry](https://discuss.ocaml.org/u/coventry)\
**Post date:** [August 19, 2017, 10:19am UTC](https://discuss.ocaml.org/t/using-a-set-in-a-module-type/737/6 "2017-08-19T10:19:08Z")

</div>

Thanks, gsg. That worked.
