I am trying to make a library that provides two different implementations of the same interface. But I am getting stuck with a puzzling error that tells me that my second implementation ‘doesn’t match’ the interface.
For the sake of simplicity I’ve boiled it down to something very simple. A ‘Box’ type that has just one funtion to make
a Box.
file: box.mli
type 'a t
val make : 'a -> 'a t
file: box.ml
type 'a t = Box of 'a
let make x = Box x
So far everything is fine. This compiles, no errors and I think it does what I want.
Now for the second implementation I tried something like this:
file: altbox.mli
include module type of Box
file: altbox.ml
type 'a t = {contents: 'a}
let make x = {contents=x}
But I get an error like this:
File "lib/altbox.ml", line 1:
Error: The implementation lib/altbox.ml
does not match the interface lib/.playground.objs/byte/playground__Altbox.cmi:
Type declarations do not match:
type 'a t = { contents : 'a; }
is not included in
type 'a t = 'a Box.t
The type 'a t is not equal to the type 'a Box.t
File "lib/box.mli", line 1, characters 0-9: Expected declaration
File "lib/altbox.ml", line 1, characters 0-26: Actual declaration
I think I need some way to tell the type checker that I don’t want Altbox.t
to be the same type as Box.t
but rather a brand new type of its own but just following the same signature patterns as the Box module (i.e isomorphic replacing Box.t with a brand new type). But I just can’t figure out how to do that.
Some things I tried:
altbox.mli
type 'a t
include module type of Box with type t = t
Error: A type variable is unbound ...
Okay, that make sense… I need to say 'a t
So I try:
type 'a t
include module type of Box with type 'a t = 'a t
Error:
File "lib/altbox.mli", line 2, characters 8-48:
2 | include module type of Box with type 'a t = 'a t
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Error: In this `with' constraint, the new definition of t
does not match its original definition in the constrained signature:
Type declarations do not match:
type 'a t = 'a t
is not included in
type 'a t = 'a Box.t
The type 'a t/2 is not equal to the type 'a t/1
File "lib/box.mli", line 1, characters 0-9:
Definition of type t/1
File "lib/altbox.mli", line 1, characters 0-9:
Definition of type t/2
File "lib/box.mli", line 1, characters 0-9: Expected declaration
File "lib/altbox.mli", line 2, characters 32-48: Actual declaration
I don’t understand this error or how to resolve it.