views:

165

answers:

2

I'm trying to define type like:

type aaa = NULL | {a: int; b: int};;

But the compiler does not allow to do it. I'm not sure of the reason why we can't mix record type with anything else.

I need to match a value if it is the record type or null record and I'm tired of creating dummy record like {a = -999; b = -999}.

is there a better way ?

+5  A: 

The "record" part of the definition has to be done in a separate type. Then you can wrap that in an "option" type if you want to express "None" or "Some value".

type aaa = {a: int; b: int}
type bbb = aaa option
newacct
+6  A: 

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
Victor Nicollet
Brilliant answer, Unification is really a headache, I can't get the whole picture behind it yet
martani_net