# \[Question\] Functor sharing constraint

**URL:** <https://discuss.ocaml.org/t/question-functor-sharing-constraint/5508>\
**Category:** Learning\
**Created:** [April 13, 2020, 6:39am UTC](https://discuss.ocaml.org/t/question-functor-sharing-constraint/5508 "2020-04-13T06:39:34Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![hss](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/hss/32/1489_2.png) [@hss](https://discuss.ocaml.org/u/hss)\
**Post date:** [April 13, 2020, 6:39am UTC](https://discuss.ocaml.org/t/question-functor-sharing-constraint/5508/1 "2020-04-13T06:39:34Z")

</div>

Hi 🙂

I’d like to make a general queue , so I’m using functor to generate queue structure like Map.Make()

```auto
  1 module type QueueType = sig
  2 type t
  3 end
  4 
  5 module Int_Queue = struct
  6 type t = int list
  7 end
  8 
  9 module type Queue = sig
 10 type data
 11 
 12 val is_empty : data -> bool
 13 end
 14 
 15 module Make(Q : QueueType) : Queue with type data = Q.t = struct
 16 type data = Q.t
 17 
 18 let is_empty l = true
 19 (* I'd like to handle parameter l as int list like below *)
 20 (* let is_empty l =
 21 * match l with
 22 * | _::_ -> false
 23 * | _ -> true *)
 24 end;;
 25 let _ = module A = Make(Int_Queue);;

```

If `is_empty()` is changed to commented code, ocaml says type error. I think the type of module Make is already enforced with Q.t which is int list, so module Make should know its type but it seems to be not in my case

Let me know what I’m missing.

Thank you!

---

<div class="post-metadata">

**Author:** ![Splingush](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/splingush/32/2115_2.png) [@Splingush](https://discuss.ocaml.org/u/Splingush)\
**Post date:** [April 13, 2020, 8:22am UTC](https://discuss.ocaml.org/t/question-functor-sharing-constraint/5508/2 "2020-04-13T08:22:46Z")

</div>

Hey there. Full disclamer, I’m no expert.

I think you mixed up the type of your queue and the type of your elements.

```ocaml
val is_empty : data -> bool

```

You use a queue there, so the type of your queue itself is `data`.

If you want to use the `QueueType.t` as the type of the elements in your queue, you wouldn’t expect it to always be a list. It would be some arbitrary type.  
If you look at your Queue-signature, you see that you have an abstract type there as well. There is nothing mentioned of a list.  
The list is part of the implementation, not of the signature for those that you use there.

You can use it in your Functor, and then only in there it’s known that the data is a list:

```ocaml
module Make(Q:QueueType) : Queue = struct
  type data = Q.t list
  let is_empty l = l = []
end

module IntQueue = Make(struct type t = int end)

```

---

<div class="post-metadata">

**Author:** ![hss](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/hss/32/1489_2.png) [@hss](https://discuss.ocaml.org/u/hss)\
**Post date:** [April 13, 2020, 11:06am UTC](https://discuss.ocaml.org/t/question-functor-sharing-constraint/5508/3 "2020-04-13T11:06:36Z")

</div>

Hi @Splingush 🙂

This question was inspired by `Map.Make()`. when I see the example of `Map`, it is beautiful because they provide the same logic as a given type of the key. So, I searched how it works and found the keyword that was `functor` and `sharing constraints`.

So, I’d like to implement simple anything like Map.Make() .

1. Provide the same logic of Queue.
2. Take `module` whose specified the which key type.

I implemented this feature without `functor` and `sharing constraints` using just one module and polymorphic type, but I’d like to experience `functor` and `sharing constraints` in my code.

---

<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:** [April 13, 2020, 4:18pm UTC](https://discuss.ocaml.org/t/question-functor-sharing-constraint/5508/4 "2020-04-13T16:18:11Z")

</div>

You may be misreading the definition of your functor argument. When you write,

```ocaml
module Make(Q : QueueType) : Queue with type data = Q.t 

```

you are stating that your functor works for any module `Q` that implements the specification `QueueType`, in other words for any module that define some black-box type `t`. At this point, there is no relationship at all between this type and any other type (like the type `Int_queue.t`).

If you wanted to express that the fact the type of the queue is a list of some elements, you need to add more information to your argument signature. Something like

```ocaml
module type Monomorphic_list = sig
  type elt
  type t = elt list
end
module Make(Q: Monomorphic_list): Queue with type data = Q.t = struct
  type data = Q.t
  let is_empty = function [] -> true | _ -> false
end

```
