Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OCaml constructor unpacking

Tags:

syntax

ocaml

Is it possible to unpack a type by binding its data to a single value instead of a tuple?

# type foo = Foo of int * string;;
type foo = Foo of int * string
# Foo (3; "bar");;
  Foo (3; "bar");;
Error: The constructor Foo expects 2 argument(s),
       but is applied here to 1 argument(s)
# Foo (3, "bar");;
- : foo = Foo (3, "bar")

# (* Can this possibly work? *)
# let Foo data = Foo (3, "bar");;
  let Foo data = Foo (3, "bar");;
Error: The constructor Foo expects 2 argument(s),
       but is applied here to 1 argument(s)

# (* Here is the version that I know works: *)
# let Foo (d1, d2) = Foo (3, "bar");;
val d1 : int = 3
val d2 : string = "bar"

Is this syntactically possible?

like image 235
Nick Heiner Avatar asked Apr 24 '12 22:04

Nick Heiner


1 Answers

This is a tricky part of OCaml syntax. If you define your type as you show, its constructor Foo expects two values in parentheses. And it always has to be two values, it's not a single value that's a tuple.

If you're willing to use a different type, you can do something more like what you want:

# type bar = Bar of (int * string);;
type bar = Bar of (int * string)
# let Bar data = Bar (3, "foo");;
val data : int * string = (3, "foo")
# let Bar (d1, d2) = Bar (3, "foo");;
val d1 : int = 3
val d2 : string = "foo"

When declared this way, the constructor Bar expects one value that's a tuple. This can be more flexible, but it also takes a little more memory to represent it, and a little longer to access the parts.

like image 157
Jeffrey Scofield Avatar answered Nov 15 '22 10:11

Jeffrey Scofield