The type constraint expression is used to declare (or restrict) the type of some expression. It takes the form
Typically such an expression gets wrapped in parentheses to make sure the lexical scope is as intended, but this is not required.
One typical use is to declare the argument types for a function.
For example the function
fun add (x, y) = x + y;
will default to doing integer addition, because there is no information available at compiletime from which to infer the types of the arguments, and integer is the default in such cases.
This can be overridden by writing
fun add (x: Float, y: Float) = x + y;
to force floating point addition, or
fun add (x: String, y: String) = x + y;
to force string concatenation.
Such declarations can also be just good documentation in cases where it may be unclear what type is involved or intended.
A type constraint expression is legal anywhere an expression is legal. For example we might instead have written
fun add (x, y) = (x: Float) + (y: Float);
fun add (x, y) = (x: String) + (y: String);
One situation in which an explicit type declaration is frequently necessary is when setting a variable to an empty list:
empty = ;
Here the compiler has no way of knowing whether you have in mind a list of ints, floats, strings, or Library of Congresses. It will probably guess wrong, resulting in odd error messages when you later use the variable. Consequently, you will usualy instead write something like
empty = : List(String);