The way I understand it is that when a type has multiple variants (multiple member variables prefixed with #
), it allows you to choose (and test for) which of those variants it is. You can only choose one of them at a given time. Your example only has one variant, so it might work but it’s not very useful.
A better example might be with shapes:
public type Shape = {
#square: Nat;
#circle: Nat;
#rectangle: { width: Nat; height: Nat };
};
If I choose to create an instance of the square
variant of Shape
, I cannot specify a width and height, I can only specify the one Nat
that the square
variant has.
Some examples of instantiation would look like this:
var mySquare = #square 2
var myCircle = #circle 3
var myRectangle = #rectangle { width=4; height=5; }
*note that the error you were getting on t1
is because you unnecessarily used curly braces and the compiler thought you were trying to create a block.
Variants allow you to achieve a type of polymorphism when used in this way. All these objects are Shape
s and can be passed around as such, but they each have their own data specific to them, as though they were more specific subclasses of Shape
.
Variants also let you do some pretty cool stuff with pattern matching, for example you can switch on which variant it is. See the tree example, which does something different depending on whether a node is a leaf or a branch. This is kind of like an enum, except each possible value for the enum can also contain extra data, like the radius or width/height in my Shape
example. If you just want a simple enum, you can specify the variants without specifying that the variants can contain any data:
public type Shape = {
#square;
#circle;
};
If you want every instance of Shape
to contain certain data, leave the #
off and they’ll all get the member variable:
public type Shape = {
#square;
#circle;
size: Nat;
};
If I’ve said anything wrong or incomplete, I hope someone at dfinity will correct me. I’m new to all this too.