← Back to AILP Home

Enum

Overview

Enumerations define a set of named integer constants. Backed by int64 at the ABI level. Plain enums (no payload variants) map to a single i64 discriminant. Tagged enums (one or more payload variants) map to { i64, [N × i8] } — a discriminant plus a payload slot. Since v0.2.39. Tagged enums and derive(Display/Eq) added in v0.36.x.

Declaration

enum:Color = { RED, GREEN, BLUE };                        // auto-numbered: 0, 1, 2
enum:HttpStatus = { OK = 200, NOT_FOUND = 404, ERROR = 500 };  // explicit values
enum:Mixed = { A, B = 10, C };                            // C = 11 (continues from last)

Tagged Variants (Payload Enums)

Variants may carry a payload of any type (including another enum):

enum:Status = { OK, FAIL };

enum:Event = {
    None,                  // plain variant (no payload)
    WithStatus(Status)     // tagged variant: payload is Status enum
};

Event:e = Event.WithStatus(Status.OK);

Destructuring with pick:

pick (e) {
    (Event.WithStatus(s)) {         // binds s : Status
        pick (s) {
            (Status.OK)   { drop println("ok"); },
            (Status.FAIL) { drop println("fail"); },
            (*) {},
        }
    },
    (Event.None) {},
    (*) {},
}

The payload type can be a primitive, a struct, or another enum.

derive(Display)

#[derive(Display)] synthesises a Display impl whose output is: - Plain variant: the variant name (e.g. "RED") - Tagged variant: "VariantName(payload)" (e.g. "Hello(42)")

#[derive(Display)]
enum:Msg = { Hello(int32) };

Msg:m = Msg.Hello(42i32);
string:s = `&{m}`;   // "Hello(42)"

derive(Eq)

#[derive(Eq)] synthesises an Eq impl that compares discriminants. For tagged enums the payload is not compared — only the variant tag. Use raw e.eq(other) to suppress the implicit Result<bool> wrapping:

#[derive(Eq)]
enum:Season = { Spring, Summer, Autumn, Winter };

Season:a = Season.Summer;
Season:b = Season.Summer;
Season:c = Season.Winter;

bool:same = raw a.eq(b);  // true
bool:diff = raw a.eq(c);  // false

Usage

Color:my_color = Color.RED;
int64:val = Color.GREEN;     // enums convert to int64

pick (my_color) {
    (Color.RED)   { drop println("Red"); },
    (Color.GREEN) { drop println("Green"); },
    (Color.BLUE)  { drop println("Blue"); },
    (*) {}
}

Enum comparison:

Color:a = Color.RED;
Color:b = Color.BLUE;
if (a != b) {
    drop println("Different colors");
}

Rules

Related