I am trying to solve the expression problem in Rust. I have defined a sum type of terms:
#[derive(Clone, Debug, PartialEq)]
pub enum Term {
True,
False,
Not(Box<Term>),
...
}
The compiler and documentation say Box
is needed for recursive terms because a structure cannot contain itself (infinite regress), and just plain &Term
would not be enough to establish that a term owns its subterms. Okay, so far so good.
Now I'm trying to write a function that simplifies terms according to the definitions of the operators, e.g. not true = false:
impl Term {
pub fn simplify(self) -> Term {
let a = self.map(Term::simplify);
match a {
Term::Not(Box(Term::True)) => Term::False,
_ => a,
}
}
pub fn map(self, f: fn(Term) -> Term) -> Term {
match self {
Term::True
| Term::False => self,
Term::Not(a) => Term::Not(Box::new(a.map(f))),
_ => panic!(),
}
}
}
but the compiler doesn't like any version of it that I have tried so far.
Term::Not(Term::True)
is not valid because a Box
needs to go in between.
Term::Not(Box::new(Term::True))
is valid when making a term, but not as a pattern match expression (which cannot contain function calls).
Term::Not(Box(Term::True))
is not valid either.
What is the right way to do this in Rust?