When do I need to prefix constructors with the module name?

I had an understanding that, to use a constructor from an module A that is not opened, I have to prefix it with the module name. However, I’ve noticed sometimes OCaml is clever enough to find the correct constructor from the unopened module, and can even select the correct one from candidates having the same name, so the following compiles:

module A = struct
    type t = Foo | Bar
end

type a = Foo | Bar
type b = Foo | Bar

let f = function
    | A.Foo -> A.Bar
    | Bar -> Foo
let a : a = Bar
let b : b = Foo

It seems that this happens whenever OCaml already knows the type of the “hole” to be filled. Is this true? Is this lovely feature documented somewhere?

I’m not sure it is but, a long time ago, Gabriel wrote a series of blog posts about it.

1 Like

Yes, this is called type-directed disambiguation: the “expected” type of an expression will be used to disambiguate constructors and record labels. See OCaml - The core language for more.

Cheers,
Nicolas

3 Likes

And in case you are interested in the history of the feature, you may enjoy reading Type-based selection of label and constructors | LexiFi.

Cheers,
Nicolas

Thank you! It’s always fun to learn about the evolution and design rationale of language features :slight_smile: Will dive into these links when I have more time!