Unit, Option, Pattern matching
Optional values are a pervasive programming pattern in OCaml. Since Michelson and LIGO are both inspired by OCaml, optional types are available in LIGO as well. Similarly, OCaml features a unit type, and LIGO features it as well. Both the option type and the unit types are instances of a more general kind of types: variant types (sometimes called sum types).
#
The unit TypeThe unit
type in Michelson or LIGO is a predefined type that
contains only one value that carries no information. It is used when
no relevant information is required or produced. Here is how it used.
In JsLIGO, the unique value of the unit
type is unit
.
#
Variant typesA variant type is a user-defined or a built-in type (in case of options) that defines a type by cases, so a value of a variant type is either this, or that or... The simplest variant type is equivalent to the enumerated types found in Java, C++, JavaScript etc.
Here is how we define a coin as being either head or tail (and nothing else):
The names Head
and Tail
in the definition of the type coin
are
called data constructors, or variants. In this particular, they
carry no information beyond their names, so they are called constant
constructors.
In general, it is interesting for variants to carry some information, and thus go beyond enumerated types. In the following, we show how to define different kinds of users of a system.
In JsLIGO, a constant constructor is equivalent to the same constructor
taking an argument of type unit
, so, for example, Guest ()
is the
same value as Guest (unit)
.
There are cases where several sum types match a given constructor.
In the example below, types t1
to t6
are all possible types for x
.
In this case, the compiler will choose one of these types as the type of the expression, and throw a warning stating that other types are possible.
You can add a type annotation to remove this ambiguity.
NOTE : The compiler will choose in priority the latest matching sum type in the current scope,
if no type is defined in this scope, it will look in the latest module, if not in the second latest etc.
Below, it will choose t1
, and if t1
didn't match it would have chosen t2
, otherwise t3
, etc.
#
Optional valuesThe option
type is a predefined variant type that is used to express
whether there is a value of some type or none. This is especially
useful when calling a partial function, that is, a function that is
not defined for some inputs. In that case, the value of the option
type would be None
, otherwise Some (v)
, where v
is some
meaningful value of any type. An example in arithmetic is the
division operation:
You can extract the value of a Some (v)
with the function Option.unopt (Some (v))
. In case the value is None
, this will fail with an error.
The proper way to deal with optional values is by means of pattern matching.
#
Pattern matchingPattern matching is similar to the switch
construct in
JavaScript, and can be used to route the program's control flow based
on the value of a variant, record, tuple, or list.
A component of a pattern can be discarded by using a wildcard _
instead of a variable name.
LIGO will warn about unused variables bound in patterns in the same
way that function arguments are warned about. Variable names beginning
with _
can be used as a binder to prevent warnings.
Note: JsLIGO only supports basic pattern matching at the moment. This will change in the future.
#
Match on variantsHere is a function that transforms a colour variant type to an int.
#
Matching records or tuplesFields of records and components of tuples can be destructured. Record pattern variables can be renamed.
Pattern-matching on records and tuples are not supported in JsLIGO yet.
#
Match on lists#
Deep patternsPattern matching can also be used for nested patterns.