Composite types
Archetype provides user-defined composite types on top of basic types.
Tuple
A tuple is a list of anonymous values of different types. The type is a list of types separated by *
. A tuple literal is a list of values separated by ,
and surrounded by parentheses.
For example:
const t : string * nat = ("a string", 2)
It is represented in Michelson as a right-comb pair of values.
Record
A record is a list of named fields of different types. It is declared by the record
keyword followed by a list of pairs of an identifier and a basic type or a composite type. It cannot be recursive though.
For example:
record voter {
weight : nat; /* weight is accumulated by delegation */
voted : bool; /* if true, that person already voted */
delegate : option<address>; /* person delegated to */
vote : nat; /* index of the voted proposal */
}
Default value
It is possible to specify the default value of a record field.
For example, the following declaration specifies that the default values of voted
and delegate
fields:
record voter {
weight : nat;
voted : bool = false;
delegate : option<address> = none;
vote : nat;
}
The effect is that fields with a default value may not be specified when creating a record value. For example, the following creates a voter
record without specified values for these fields:
var v = { weight = 1; vote = 234523 };
Michelson representation
By default, the Michelson structure of a record is a right comb of pairs.
It means for example that the Michelson type of the voter
record declared above is:
pair (nat %weight) (pair (bool %voted) pair ((option %delegate address) (nat %vote)))
It is possible to specify another structure and/or other field names, with the as
keyword, as illustrated below:
record voter {
weight : nat;
voted : bool = false;
delegate : option<address> = none;
vote : nat;
} as (((w, has_voted), (del, vote)))
The resulting Michelson type is then:
pair (pair (nat %w) (bool %has_voted)) (pair (option %del address) (nat %vote))
Enum
An enumeration is a union type of a fixed set of named types. It is declared by the enum
keyword followed by an identifier and the list of names types separated by |
.
For example:
enum juice_size =
| Small
| Medium
| Large
Named types may take an argument of any basic type or composite type (tuple, record, ...) (it cannot be recursive though).
For example, the type RGB
below is the tuple of 3 nat
:
enum color =
| RGB<nat * nat * nat>
| Hex<bytes>
| Css<string>
Michelson representation
When named types have no argument (like in juice_size
example above), they are represented by an int
value from 0
to n-1
if n
is the number of named types.
With argument (like in color
example above), named types are represented with imbricated or
values. For example the Michelson type of color
is:
or (pair %RGB nat (pair nat nat)) (or (bytes %Hex) (string %Css))
States
When designing the contract as a state machine, the states
keyword is used to declare the list of states.
For example:
states =
| Pending initial
| Shipped
| Accepted
| Rejected
| Canceled
One state may be followed by the initial
keyword to specify the initial machine's state. If omitted, the first state is the initial state.
The Michelson representation of the contract state is a storage variable named _state
and typed nat
.
Event
Archetype defines events with the event
keyword declaration. An event may possess several fields, like a record.
For example the following declares the HighestBidIncreased event with two fields bidder and amount:
event HighestBidIncreased {
bidder : address;
amount : tez
}