Enums are a data type composed of a fixed set of inner data types, known as variants. A common use is to define an "optional" or "maybe" type that will either have a "something" of X, or a nothing.
In addition to providing an Option
as part of predefined data types, it is
also possible to create new enums.
By default, an enum is flat. The variants of a flat enum are placed into the module's namespace.
enum FlatRgb
{
Red,
Green,
Blue
define is_blue: Boolean
{
match self: {
case Blue: return true
else: return false
}
}
}
var v = Blue
print(v.is_blue()) # true
print(v) # Blue
The alternative is a scoped enum. Variants of a scoped enum are kept within the enum.
scoped enum ScopedRgb
{
Red,
Green,
Blue
define is_blue: Boolean
{
match self: {
case ScopedRgb.Blue:
return true
case ScopedRgb.Red,
ScopedRgb.Green:
return false
}
}
}
var v = ScopedRgb.Blue
print(v.is_blue()) # true
print(v) # ScopedRgb.Blue
In both cases, variants are sealed inside of the enum they are declared in. It
is not possible to, for example, declare a variable of type Some
.
Similar to classes, enum allow declaration of methods. Enum methods do not
support any qualifiers. All enum methods act as they are public
, and receive
self
as a hidden first parameter. Enum methods do not allow a scope because
they cannot inherit or be inherited from.
enum Rgb
{
Red,
Green,
Blue
define is_blue: Boolean
{
with self as Blue: {
return true
else:
return false
}
}
}
var v = Blue
print(v.is_blue()) # true
# An alternative way of calling the above.
print(Rgb.is_blue(v)) # true
print(v) # Blue
It is possible for a variant to take arguments. Those arguments can include the
enum itself. Variants that take values can be called like a Function
, but they
are not Function
values.
Variants support all argument types, except optional arguments.
enum Tree
{
Leaf(Integer),
Branch(Tree, Tree)
define walk: Integer
{
match self: {
case Leaf(value):
return value
case Branch(left, right):
return left.walk() + right.walk()
}
}
}
var tree =
Branch(
Branch(
Leaf(10),
Leaf(20)
),
Leaf(30)
)
print(tree.walk()) # 60
Variants can also have variable arguments.
enum Tree
{
Leaf(Integer),
Branch(Tree...)
define walk: Integer
{
match self: {
case Leaf(value):
return value
case Branch(targets):
var total = 0
for i in 0...targets.size() - 1: {
total += targets[i].walk()
}
return total
}
}
}
var tree =
Branch(
Branch(
Leaf(10)
),
Leaf(20),
Leaf(30),
Leaf(40)
)
print(tree.walk()) # 100
Keyword arguments are also supported.
enum Color
{
Blue,
Green,
Red,
RGB(:red Integer, :green Integer, :blue Integer)
define to_i: Integer
{
match self: {
case Blue:
return 0x0000ff
case Green:
return 0x00ff00
case Red:
return 0xff0000
case RGB(r, g, b):
return (r << 16) +
(g << 8) +
b
}
}
}
var v = RGB(:red 0xff,
:blue 0,
:green 0)
print(Green.to_i()) # 65280
print(v.to_i()) # 16711680
Variants support call piping.
{
var v = Option.unwrap(Some(1))
print(v) # 1
}
{
var v = 1 |> Some |> Option.unwrap
print(v) # 1
}