Reputation: 5637
Let's consider two different but similar sum types:
(* Two different types, but same/similar definitions *)
type t = Foo of int
type t' = Foo of int
and then let's imagine we had a function that could work with either type at face value:
(* Function that could work with either t or t' *)
let f x =
match x with
| Foo n -> n
Is it possible for that function f
to actually work with both types t
and t'
when they are both sum types?
I know that when the function is processed for its type, x
will be inferred to have type t'
and then not be compatible with type t
.
let _ =
let (a : t) = Foo 1 in
let (a' : t') = Foo 1 in
let _ = f a' in (* This is fine. *)
let _ = f a in (* This will throw a type error. *)
()
Alternatively, I know using a simpler type would work fine, like:
type t = int
type t' = int
let g x = x + 1
let _ =
let (a : t) = 1 in
let (a' : t') = 1 in
let _ = g a' in (* This is fine. *)
let _ = g a in (* This is fine. *)
()
I'm guessing this works because g
will get inferred to have the type int -> int
which is compatible with both t
and t'
in this case since they are truly of the same type, whereas in my previous example they were separate sum types that just happened to have the same structure.
So to reiterate my question, is it possible for that function f
to actually work with both types t
and t'
when they are both sum types?
I'm asking because I want to know if I have to write the same function for both t
and t'
(essentially duplicating code since both types would be handled exactly the same).
Upvotes: 1
Views: 62
Reputation: 6140
Your types t
and t'
may have similar definition, but they are different types.
However, you can go around that.
Since in the comments you stated that you had no control over the type declaration, the only way I see to solve your problem is the functor way.
type a = A
type a' = A
module type T = sig type t = A end
module A ( X : T ) = struct open X let f = function A -> () end
module T1 = struct type t = a = A end
module T2 = struct type t = a' = A end
module A1 = A(T1)
module A2 = A(T2)
However, if a library gave you two types like that, it is probable there is a reason for it and a way to do things differently provided by the library itself.
Upvotes: 3