Skip to content
Kavachकवच

Unions: Declaring

● Intermediate4 min

type Name = A | B(field: Type) | … declares a union.

type Shape = Circle(radius: Float) | Rect(width: Float, height: Float)

fn area(s: Shape) -> Float {
    match s {
        Shape.Circle(radius) => 3.14 * radius * radius
        Shape.Rect(width, height) => width * height
    }
}

fn main() {
    print(area(Shape.Circle(radius: 2.0)))
    print(area(Shape.Rect(width: 3.0, height: 4.0)))
}

The program ran and printed:

kavach run union.kav

12.5612.0
union.kav: Kavach code, then what running it prints

A variant is always written with its union's name, as a value and in a match case alike: Shape.Circle(radius: 2.0), Status.Paid, FsError.NotFound(path). So what a name means never depends on which other unions exist. Printing still shows the variant alone: print(Status.Paid) prints Paid.

A bare variant name is an error that says what to write, and kavach fix writes it for you:

type Shape = Circle(radius: Float) | Rect(width: Float, height: Float)

fn area(s: Shape) -> Float {
    match s {
        Circle(radius) => 3.14 * radius * radius,
        Shape.Rect(width, height) => width * height,
    }
}

fn main() {
    print(area(Circle(radius: 1.0)))
}
src/main.kav, before: Kavach code
terminal
kavach check
error: `Circle` is a variant of `Shape`: write `Shape.Circle` (decision 0070)
 --> src/main.kav:5:9
  |
5 |         Circle(radius) => 3.14 * radius * radius,
  |         ^^^^^^

error: `Circle` is a variant of `Shape`: write `Shape.Circle` (decision 0070)
  --> src/main.kav:11:16
   |
11 |     print(area(Circle(radius: 1.0)))
   |                ^^^^^^
kavach fix src
src/main.kav: Write `Shape.Circle`
src/main.kav: Write `Shape.Circle`
kavach run
3.14

A variant may have the name of a built-in type, such as List or Error: Kind.List is the variant, and List stays the type.