When should I use single case constructors or type aliases?

@nojb @vlaviron

Kind of nitpicking, but I just came up with one scenario where type person = Person of {...} can prevent the error but type person = {...} can’t.

The following code has a logical error, but compiles:

type dog = {name: string}
type cat = {name: string}

let has_long_name (cat: cat) = String.length cat.name > 10

let _ = (
  let my_dog = {name = "Brian"} in (* x *)
  has_long_name my_dog
)

The problem: at the line marked with x, the programmer thought my_dog has type dog, but in fact the inferred type is cat.

This won’t happen if we have type dog = Dog of {name: string}.

You can also avoid this logic issue by using modules, which is what we typically do:

module Dog = struct
  type t = { name : string }
end

module Cat = struct
  type t = { name : string }
end

Now we will have to create and pattern-match the record types using their explicit module names eg { Dog.name = "Brian" }.

1 Like