Consider the two following code snippets
type atp
type smt
type _ config =
| ConfigSmt : smt config
| ConfigAtp : atp config
let digest : smt config -> unit =
fun cfg -> match cfg with ConfigSmt -> ()
and
module M = struct
type atp
type smt
type _ config =
| ConfigSmt : smt config
| ConfigAtp : atp config
end
let digest : M.smt M.config -> unit = fun cfg ->
match cfg with ConfigSmt -> ()
and let’s call nomod.ml
a file that contains the first snippet and mod.ml
another file that contains the second snippet.
I’d expect both files to compile, and in particular in both cases I’d expect the type checker to infer that the case ConfigAtp
isn’t possible,
- either because
ConfigAtp
is of typeM.atp
, which isn’tM.smt
inmod.ml
and - because
ConfigAtp
is of typeatp
which isn’tsmt
inmod.ml
.
However, nomod.ml
type checks but not mod.ml
doesn’t: using ocaml 4.14.1,
$ ocamlc nomod.ml
but
$ ocamlc mod.ml
File "mod.ml", line 10, characters 2-32:
10 | match cfg with ConfigSmt -> ()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Warning 8 [partial-match]: this pattern-matching is not exhaustive.
Here is an example of a case that is not matched:
ConfigAtp
Why does the type checker fails to infer that ConfigAtp
is of type M.atp M.config
which shouldn’t be equivalent to M.smt M.config
?