Reputation: 122432
Given a type:
type coords = int * int
The following works:
# let c : coords = 3, 4;;
val c : coords = (3, 4)
I would also like to be able to do:
# let (x, y) : coords = 3, 4;;
let (x, y) : coords = 3, 4;;
Error: Syntax error
But it complains about a syntax error on :
. Is this syntactically possible?
Upvotes: 5
Views: 3553
Reputation: 27286
The syntax
let x : t = ...
means that you are, in most cases needlessly, telling the compiler that the type of the name x is t (or maybe you just want to add this type information for readability purposes). In your example:
let (x,y) : coords =
you have to ask yourself: what is the name whose type is coords? Clearly you define no such name, the type of x is int and so is the type of y. There's no name with type coords on the left side. If you already have a coords value, you can split it up as below:
# type coords = int*int ;;
type coords = int * int
# let c:coords = 3,4 ;;
val c : coords = (3, 4)
# let x,y = c;;
val x : int = 3
val y : int = 4
In the above example on the line
let c: coords = 3,4 ;;
you are actually letting the compiler that the name c should be assigned a coords type (otherwise int*int will be used as the type).
Upvotes: 1
Reputation: 107759
The syntax let x : t = …
is the no-argument case of the more general syntax
let f a1 … an : t = …
where t
is the return type of the function f
. The identifier f
has to be just an identifier, you can't have a pattern there. You can also write something like
let (x, y) = …
Here (x, y)
is a pattern. Type annotations can appear in patterns, but they must be surrounded by parentheses (like in expressions), so you need to write
let ((x, y) : coords) = …
Note that this annotation is useless except for some cosmetic report messages; x
and y
still have the type int
, and (x, y)
has the type int * int
anyway. If you don't want coordinates to be the same type as integers, you need to introduce a constructor:
type coords = Coords of int * int
let xy = Coords (3, 4)
If you do that, an individual coordinate is still an integer, but a pair of coordinates is a constructed object that has its own type. To get at the value of one coordinate, the constructor must be included in the pattern matching:
let longitude (c : coords) = match c with Coords (x, y) -> x
Upvotes: 9