# Problem with sharing constraint

**URL:** <https://discuss.ocaml.org/t/problem-with-sharing-constraint/10800>\
**Category:** Learning\
**Created:** [November 15, 2022, 7:54pm UTC](https://discuss.ocaml.org/t/problem-with-sharing-constraint/10800 "2022-11-15T19:54:24Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![borisd](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/borisd/32/3965_2.png) [@borisd](https://discuss.ocaml.org/u/borisd)\
**Post date:** [November 15, 2022, 7:54pm UTC](https://discuss.ocaml.org/t/problem-with-sharing-constraint/10800/1 "2022-11-15T19:54:24Z")

</div>

Here’s an example:

```auto
module type S = sig
  type msg
  val dispatch : msg -> unit
end

module A : S = struct
  type msg
  let dispatch _ = ()
end

module B = struct
  type msg
  module C = (A : S with type msg = msg)
end

```

This results in an error:

```auto
module C = (A : S with type msg = msg)
                   ^
Error: Signature mismatch:
       Modules do not match:
         sig type msg = A.msg val dispatch : msg -> unit end
       is not included in
         sig type msg = msg val dispatch : msg -> unit end
       Type declarations do not match:
         type msg = A.msg
       is not included in
         type msg = msg
       The type msg/1 is not equal to the type msg/2

```

What does this error mean? Why can’t the two abstract types get unified?

---

<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:** [November 15, 2022, 8:10pm UTC](https://discuss.ocaml.org/t/problem-with-sharing-constraint/10800/2 "2022-11-15T20:10:49Z")

</div>

Your module declarations

```ocaml
module A : S = struct
  type msg
  ...
end

module B = struct
  type msg
  ...
end

```

creates two fresh and unrelated types named `msg` (or more precisely `A.msg` and `B.msg`) .  
Those types are distinct and it would be a mistake to consider them equal.

---

<div class="post-metadata">

**Author:** ![thierry-martinez](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/thierry-martinez/32/1481_2.png) [@thierry-martinez](https://discuss.ocaml.org/u/thierry-martinez)\
**Post date:** [November 16, 2022, 3:13pm UTC](https://discuss.ocaml.org/t/problem-with-sharing-constraint/10800/3 "2022-11-16T15:13:36Z")

</div>

If you want to make `A.msg` and `B.msg` equal, you can write:

```auto
module B = struct
  type msg = A.msg
  module C = (A : S with type msg = msg)
end

```

---

<div class="post-metadata">

**Author:** ![borisd](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/borisd/32/3965_2.png) [@borisd](https://discuss.ocaml.org/u/borisd)\
**Post date:** [November 17, 2022, 4:14am UTC](https://discuss.ocaml.org/t/problem-with-sharing-constraint/10800/4 "2022-11-17T04:14:10Z")

</div>

The problem I’m trying to solve is that type `msg` will be provided by the user of the library, and since the library code cannot refer to the user modules unless I add functors to the api, I was hoping that there is a way to use sharing constraints to relate the `msg` type in all library modules. Maybe you can suggest strategies for dealing with this problem other than using functors?

---

<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:** [November 17, 2022, 9:44am UTC](https://discuss.ocaml.org/t/problem-with-sharing-constraint/10800/5 "2022-11-17T09:44:29Z")

</div>

If the type is provided by the user, you cannot define it yourself. Depending on the level of polymorphism needed, you can use either define functions on record of functions (or objects), or move to functors.  
For instance,

```ocaml
type msg = { dispatch: unit -> unit }
let do_something {dispatch} = dispatch ()

```

or

```ocaml
module Do_something(X: S) = struct
  ...
end

```
