User-defined data types

A user-defined data type is introduced with the type keyword and a modifier unique or structural. The modifier indicates if the type is unique by its name, or if it is unique only by its structure. (See Types for an informal description of Unison's type system.)

For example:

structural type Optional a
structural type Optional a
  = lib.base.Optional.Some a
  | lib.base.Optional.None

or

The = sign splits the definition into a left-hand side and a right-hand side, much like term definitions.

The left-hand side is the data type being defined. It gives a name for the data type and declares a new type constructor with that name (here it's named Optional), followed by names for any type arguments (here there is one and itā€™s called a). These names are bound as type variables in the right-hand side. The right-hand side may also refer to the name given to the type in the left-hand side, in which case it is a recursive type declaration. Note that the fully saturated type construction Optional Nat is a type, whereas Optional by itself is a type constructor, not a type (it requires a type argument in order to construct a type).

The right-hand side consists of zero or more data constructors separated by |. These are data constructors for the type, or ways in which values of the type can be constructed. Each case declares a name for a data constructor (here the data constructors are Optional.None and Some), followed by the types of the arguments to the constructor.

When Unison compiles a type definition, it generates a term for each data constructor. Here they are the terms Some : a -> Optional a, and Optional.None : Optional a. It also generates patterns for matching on data (see Pattern Matching).

Note that these terms and patterns receive qualified names: if the type named x.y.Z has a data constructor C, the generated term and pattern for C will be named x.y.Z.C.

The general form of a type declaration is as follows:

<unique|structural<[<regular-identifier>]?>?> type TypeConstructor p1 p2 ā€¦ pn
  = DataConstructor_1
  | DataConstructor_2
  ..
  | DataConstructor_n