O'Caml syntactic oddities explained
Author |
Message |
wtd
|
Posted: Tue May 17, 2005 4:47 pm Post subject: O'Caml syntactic oddities explained |
|
|
Tuple types
Tuples are critical to O'Caml, and immensely useful, but their type representation can be a bit confusing.
Let's say I enter the following at the O'Caml toplevel:
code: | # let a = (42, 56.7);; |
Now it shows me:
code: | val a : int * float = (42, 56.7) |
But what the heck is "int * float"?
Well, in this case the asterisk indicates a tuple of an int and a float.
Where is this really an issue?
Fortunately O'Caml infers types very well so we almost never have to worry about this. There are at least a few places where we do have to worry about it, though.
"Algebraic" types are one example. Let's look at a simple binary tree definition.
code: | type 'a btree = Empty
| Leaf of 'a
| Branch of 'a btree * 'a * 'a btree |
Here the 'a is the generic type that can stand in for any type. The three possible forms of a binary tree are empty, a single leaf with one value, and a branch with one value and two subtrees. Each "constructor" only takes one argument which is a tuple.
Seeing this is action:
code: | let tree = Branch (Branch (Leaf 32, 56, Empty), 12, Leaf 3);; |
The other places we see this syntax is with exceptions. Let's say we have a bank_account class.
code: | class bank_account overdraft init_balance=
object (self)
val overdraft = overdraft
val mutable balance = init_balance
method current_balance = balance
method deposit amount =
balance <- balance + amount
method withdraw amount =
balance <- balance - amount
end |
Now, what if I want to raise an exception when a bad withdrawal request is made? I could create a simple Bad_withdrawal exception, but let's say I want to pass information on the amount that they tried to withdraw and how much they have available.
First, let's create the exception. It has to hold two pieces of info.
code: | exception Bad_withdrawal of int * int |
And the new class.
code: | class bank_account overdraft init_balance=
object (self)
val overdraft = overdraft
val mutable balance = init_balance
method current_balance = balance
method deposit amount =
balance <- balance + amount
method withdraw amount =
if amount > balance + overdraft then
raise (Bad_withdrawal (amount, balance))
else
balance <- balance - amount
end |
|
|
|
|
|
|
Sponsor Sponsor
|
|
|
|
|