Shared enum fields in Whiley


#1

I am still taking a look at the Whiley language. It has a feature that I explain with the code below:

#![allow(dead_code)]

type Rank = u8; // In 0 ... 8.

enum Cell1 {
    Exposed { holds_bomb: bool, rank: Rank },
    Hidden  { holds_bomb: bool, flagged: bool },
}

fn foo1(c: Cell1) -> u32 {
    let mut rank = 0;
    match c {
        Cell1::Exposed { holds_bomb: true, .. } |
        Cell1::Hidden { holds_bomb: true, .. } => rank += 1,
        _ => (),
    }
    rank
}

// -------------------

enum CellState {
    Exposed { rank: Rank },
    Hidden  { flagged: bool },
}

struct Cell2 {
    holds_bomb: bool,
    state: CellState,
}

fn foo2(c: Cell2) -> u32 {
    let mut rank = 0;
    if c.holds_bomb { rank += 1; }
    rank
}

fn main() {}

In the Whiley code example I’ve seen there’s a data structure like Cell1, the Whiley tutorial says:

Also, note that we can access the field holdsBomb without determining whether sq is hidden or not. This is because holdsBomb is contained in both ExposedSquare and HiddenSquare and, hence, is guaranteed to be present for any Square.

So in Whiley if your enum variants share a field, you can access that field directly, without a match alternative as in foo1(). In Rust you can solve the problem like in Cell2, using a struct with the shared field, that you can always access, as shown in foo2().

The Rust solution is more clean and less magic, but longer and noisier.