Hi, I’d like to understand if the following code is OK.
type t1 =
| A of int
| B of string
type t2 = A of string
let f1 v = A v (* val f1 : string -> t2 = <fun> *)
let f2 v = B v (* val f2 : string -> t1 = <fun> *)
It compiles without without any warnings, But it feels wrong that the first A
constructor of type t1
is not accessible any more, but B
still is.
The definition of f1
raises a warning:
Warning 41 [ambiguous-name]: A belongs to several types: t2 t1
The first one was selected. Please disambiguate if this is wrong.
which hints to the way to get back A
from the first type:
let f1 v = (A v:t1)
(which raises disambiguated-name
warning which is mostly safe to ignore nowadays)
Thanks, I did not get such an warning with 4.11 with just ocaml -c test.ml
Anyway, it’s clear now.
This warning is not activated by default. For quick testing, it might be useful to enable all warnings with ocamlc -w +a -c test.ml
.
A good way to disambiguate constructors is to put the types in different modules:
module T1 = struct
type t = A of int | B of string
end
module T2 = struct
type t = A of string
end
let f1 v = T1.A v (* val f1 : int -> T1.t = <fun> *)
let f2 v = T2.A v (* val f2 : string -> T2.t = <fun> *)
Modules are cheap to create, so this is easy. It also works nicely for disambiguating between record types with the same field names.
1 Like