Enum type inference on nongeneric variant

I had an idea to use an enum for simple expression building, like this.

enum Expression<'a, A, B> {
    And(A, B),
    Or(A, B),
    Rule(&'a str),
}

With this, I can build expressions...


fn main() {
    use Expression::*;

    let e1 = Rule::<(), ()>("a");
    let e2 = Rule::<(), ()>("b");
    let e3 = And(e1, e2);

    match e3 {
        And(Rule("a"), Rule("b")) => { /* ... */ }
        _ => { }
    }
}

But as you see I have to use the verbose <(), ()> syntax to be able to initialize any Rules, or else I get type inference errors.

104 |     let e1 = Rule("a");
    |         --   ^^^^ cannot infer type for type parameter `A` declared on the enum `Expression`

I wonder if I can enforce automatic inference of the variant Rule every time to be the same type. Is this possible?

Ultimately, I just want to have a collection of Expressions:

vec!(And(Or(..), ..), Rule(..), ..)

so any other way of doing that would be fine too.


Edit: I just realized I can't have differently structured rules like this in a vector anyway. Wondering what else to do instead.

I'd expect to see something like

enum Expression<'a> {
    Not(Box<Self>),
    And(Box<(Self, Self)>),
    Or(Box<(Self, Self)>),
    Rule(&'a str),
}
2 Likes