Lyric v1.6.0

Enums and pattern matching

An enum lists alternatives. A variant may carry a payload, either positionally or by name.

enum Shape {
    Circle(float),
    Rectangle(float, float),
    Triangle { a: float, b: float, c: float },
    Empty;

    fn corners(): int {
        return match (this) {
            Circle(r)       => 0,
            Rectangle(w, h) => 4,
            Triangle { a, b, c } => 3,
            Empty           => 0,
        };
    }
}

fn main(): int {
    let s = Shape.Rectangle(3.0, 4.0);
    return s.corners();
}

The ; separates the variants from the methods.

Constructing

enum Shape {
    Circle(float),
    Triangle { a: float, b: float, c: float },
    Empty,
}

fn main(): int {
    let a = Shape.Circle(2.0);
    let b = Shape.Triangle { a = 3.0, b = 4.0, c = 5.0 };
    let c = Shape.Empty;
    return 0;
}

Matching

match is exhaustive: every variant must be covered, or the last arm must be _.

enum Signal { Red, Yellow, Green, }

fn wait(s: Signal): int {
    return match (s) {
        Red    => 60,
        Yellow => 5,
        Green  => 0,
    };
}

fn main(): int { return wait(Signal.Yellow); }

Arms may bind payloads, test literals, cover ranges, combine alternatives with |, and carry a guard:

fn classify(n: int): int {
    return match (n) {
        0          => 0,
        1 | 2 | 3  => 1,
        4..=9      => 2,
        x if x < 0 => -1,
        _          => 3,
    };
}

fn main(): int { return classify(7); }

An arm whose body is an expression ends with ,. An arm whose body is a block may omit it, but a block arm must return or throw — it contributes no value.

Generic enums

The type arguments belong to the enum and precede the variant:

enum Result<T> {
    Ok(T),
    Failed { reason: string },
}

fn main(): int {
    let a = Result<int>.Ok(5);
    let b = Result<int>.Failed { reason = "empty" };

    let c: Result<int> = Result.Ok(7);      // taken from the annotation

    return match (a) {
        Ok(v) => v,
        Failed { reason } => 0,
    };
}

Where the expected type is known, the arguments may be omitted. In an argument position they cannot; write them.