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
ConfigAtpis of typeM.atp, which isn’tM.smtinmod.mland - because
ConfigAtpis of typeatpwhich isn’tsmtinmod.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?