Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using a variant type constructor with just one tuple value

# type foo = Foo of int * int
# let t = (1, 2)
# Foo t
Error: The constructor Foo expects 2 argument(s),
   but is applied here to 1 argument(s)

How is it that I must do Foo (1, 2) to avoid that error even t has the appropriate type?

like image 474
Ricardo Avatar asked Mar 19 '12 17:03

Ricardo


2 Answers

This is one of the troubling parts of OCaml syntax, in my opinion. Despite the way it looks, the constructor Foo doesn't require a 2-tuple as its argument. It requires, syntactically, two values in parentheses--but they aren't a tuple. So it's simply the case that t has the wrong type. The way to make this work is to say:

let (a, b) = t in Foo (a, b)

The problem really is that parentheses are being used for two different things (or so I claim). Once you get used to this it's not so difficult to deal with.

Edit: if you want the constructor Foo to take a single tuple, rather than two separate values, you can define it like this:

type foo = Foo of (int * int)

Then the rest of your original code will work.

like image 103
Jeffrey Scofield Avatar answered Nov 14 '22 05:11

Jeffrey Scofield


Note that the distinction between Foo of (a * b) and Foo of a * b is there for efficiency reasons: Foo of (a * b) has an argument which is a tuple, a pointer to two elements in the heap. Foo of a * b has two arguments that are directly packed with the tag, avoiding an indirection.

This is also the reason why, for example, algorithms that use association lists (for examples Hashtables with linked list buckets) sometimes define their own datatype instead of reusing ('a * 'b) list:

type ('a, 'b) assoc_list =
  | Nil
  | Cons of 'a * 'b * ('a, 'b) assoc_list

Of course in the general high-level case such specializations are not terribly important (and can hinder code reuse), but it's still nice to be able to get down to such technical details when you actually need tighter control over memory representation.

like image 45
gasche Avatar answered Nov 14 '22 04:11

gasche