Unique types

A type declaration gives a name to a type, but Unison does not uniquely identify a type by its name. Rather, the hash of a type's definition identifies the type. The hash is based on the structure of the type definition, with all identifiers removed.

For example, Unison considers these type declarations to declare the exact same type, even though they give different names to both the type constructor and the data constructors:

structural type Optional a = Some a | None

structural type Maybe a = Just a | Nothing

So a valueSome 10and a valueJust 10are in fact the same value and these two expressions have the same type. Even though one nominally has thetype Optional Natand the otherMaybe Nat,Unison understands that as the type#5isltsdct9fhcrvu ##Nat.

This is not always what you want. Sometimes you want to give meaning to a type that is more than just its structure. For example, it might be confusing that these two types are identical:

structural type Suit = Hearts | Spades | Diamonds | Clubs

structural type Direction = North | South | East | West

Unison will consider every unary type constructor with four nullary data constructors as identical to these declarations. So Unison will not stop us providing a Direction where a Suit is expected.

The unique keyword solves this problem:

unique type Suit
unique type Suit = Hearts | Spades | Diamonds | Clubs
unique type Direction
unique type Direction = North | South | East | West

When compiling these declarations, Unison will generate auniversally unique identifierfor the type and use that identifier when generating the hash for the type. As a result, the type gets a hash that is universally unique.