# Why type is not matching

**URL:** <https://discuss.ocaml.org/t/why-type-is-not-matching/3989>\
**Category:** Learning\
**Created:** [June 27, 2019, 9:15am UTC](https://discuss.ocaml.org/t/why-type-is-not-matching/3989 "2019-06-27T09:15:19Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![XVilka](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/xvilka/32/5334_2.png) [@XVilka](https://discuss.ocaml.org/u/XVilka)\
**Post date:** [June 27, 2019, 9:15am UTC](https://discuss.ocaml.org/t/why-type-is-not-matching/3989/1 "2019-06-27T09:15:19Z")

</div>

For example I have the code that wants to abstract the nature of buffer types, lets take just `string` and `bytes` for the simplicity:

```ocaml
open Core

module type Byteable = sig
   type t
   val length: t -> int
   val to_bytes: t -> bytes
end

module StringB : sig
    type t
    val length: t -> int
    val to_bytes: t -> bytes
end

module BytesB: sig
   type t
   val length: t -> int
   val to_bytes: t -> bytes
end

module StringB : Byteable = struct
   include String
   let to_bytes = Bytes.unsafe_of_string_promise_no_mutation
end

module BytesB: Byteable = struct
   include Bytes
   let to_bytes a = a
end

```

Then if I define a functor, something like:

```ocaml
(* this one just to clarify it always accepts bytes *)
val call_some_function : bytes -> unit

module Make_stuff (M : Byteable) = struct
    let do_some_weird_stuff ~data =
        let databytes = M.to_bytes data in
        call_some_function databytes
end

module MyBytes = Make_stuff (BytesB)
module MyString = Make_stuff (StringB)

```

With just this it compiles fine and well. But if I actually try to use the resulting modules function `do_some_weird_stuff` it requires `BytesB.t` type instead of `bytes` or `StringB.t` type instead of `string`.  
For example if I call something like:

```ocaml
let cool_string = "something" in
MyString.do_some_weird_stuff ~data:cool_string

```

will produce a compile error:

```auto
this expression has type string but an expression was expected of type StringB.t

```

Why does it happen?

---

<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:** [June 27, 2019, 10:27am UTC](https://discuss.ocaml.org/t/why-type-is-not-matching/3989/2 "2019-06-27T10:27:39Z")

</div>

One problem is that the signature

```auto
module StringB : sig
    type t
    val length: t -> int
    val to_bytes: t -> bytes
end

```

make the type `StringB.t` abstract. Thus outside of the module `StringB`, the only information known about `t` is that, it can be consumed by `StringB.length` or `StringB.to_byte`. In particular, there is no way to construct a value of type `t` from types outside of the module.

If you want to expose the fact that `StringB.t = string`, you need to state this equality in the signature explicitly:

```auto
module StringB : sig
    type t = string
    val length: t -> int
    val to_bytes: t -> bytes
end

```

---

<div class="post-metadata">

**Author:** ![XVilka](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/xvilka/32/5334_2.png) [@XVilka](https://discuss.ocaml.org/u/XVilka)\
**Post date:** [June 27, 2019, 10:31am UTC](https://discuss.ocaml.org/t/why-type-is-not-matching/3989/3 "2019-06-27T10:31:57Z")

</div>

Well, I tried to do

```auto
module StringB : sig
    type t = string
    val length: t -> int
    val to_bytes: t -> bytes
end

```

but it complains that this doesn’t match to the module type:

```auto
The implementation does not match the interface ....:
In module StringB:
Type declarations do not match:
  type t = StringB.t
is not included in 
  type t = string

```

```auto

```

---

<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:** [June 27, 2019, 10:36am UTC](https://discuss.ocaml.org/t/why-type-is-not-matching/3989/4 "2019-06-27T10:36:21Z")

</div>

What does the implementation look like?

---

<div class="post-metadata">

**Author:** ![XVilka](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/xvilka/32/5334_2.png) [@XVilka](https://discuss.ocaml.org/u/XVilka)\
**Post date:** [June 27, 2019, 10:37am UTC](https://discuss.ocaml.org/t/why-type-is-not-matching/3989/5 "2019-06-27T10:37:44Z")

</div>

It is already in the post:

```auto
module StringB : Byteable = struct
   include String
   let to_bytes = Bytes.unsafe_of_string_promise_no_mutation
end

module BytesB: Byteable = struct
   include Bytes
   let to_bytes a = a
end

```

---

<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:** [June 27, 2019, 10:42am UTC](https://discuss.ocaml.org/t/why-type-is-not-matching/3989/6 "2019-06-27T10:42:05Z")

</div>

So you have the same problem with `Byteable` which is not an usable module type by itself, you most probably want `Byteable with type t = string` (and `Byteable with type t = concrete_type` for other implementations).

---

<div class="post-metadata">

**Author:** ![XVilka](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/xvilka/32/5334_2.png) [@XVilka](https://discuss.ocaml.org/u/XVilka)\
**Post date:** [June 27, 2019, 10:47am UTC](https://discuss.ocaml.org/t/why-type-is-not-matching/3989/7 "2019-06-27T10:47:20Z")

</div>

Thanks, this did the job. But the original idea was to derive the type from the `String` or `Bytes` modules (`string` and `bytes` types), is this possible somehow?

---

<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:** [June 27, 2019, 10:50am UTC](https://discuss.ocaml.org/t/why-type-is-not-matching/3989/8 "2019-06-27T10:50:38Z")

</div>

In the implementation, it is possible to remove the signature constraint:

```auto
module StringB = struct
   include String
   let to_bytes = Bytes.unsafe_of_string_promise_no_mutation
end

```

and let the compiler infers the module type by itself.
