First problem: in the Objective Caml approach, you can't have clean union types without constructors. Consider the following conundrum :
type test = Null | {a : int ; b: int }
let value = { a: 0 ; b : 42 } in print_int value.a
The second line is incorrect, because value
is of an union type, and might therefore be Null
, which has no member a
. This would introduce an implicit assumption about the value of an union type, which Objective Caml avoids at all costs. This means you need a constructor.
But even that would be enough, because then you'd have an anonymous record type:
type test = Null | Pair of { a : int ; b : int }
match Pair { a : 0 ; b : 42 } with
| Null -> 0
| Pair p -> p.a
What would be the type of p
here? This could certainly be solved by allowing anonymous record types into the language, but it's not a simple addition, as such types are notoriously difficult to handle with a type unification approach and require a lot of additional constructs for support (for instance, the < ; ... >
, #type
and value :> type
constructs for handling objects).
Language designers took the easy way out, and required that all record types receive a name. Of course, if you have an exceedingly simple record, you can use a tuple:
type test = Null | Pair of int * int