An Expr describes a simple structure for algebraic expressions. Generally,
a type Expr[A] indicates that A has some structure that mirrors Expr.
To get at this symmetry, you must use the type class Coexpr[A]. This let's
us switch between types A and Expr[A], giving us the ability to extract
structure from a type A, traverse, and construct the expression tree of
A, without having to deal with A as a concrete type.
Using Coexpr let's us provide further general constructors and pattern
matchers. These are defined as the same name as the case class, but without
the Expr appended. So, we can, for example, pattern match on an instance
a of the generic type A. Suppose we wanted to map patterns like ab + ac
to a(b + c), then we could do the following:
a match {
case Add(Mul(a, b), Mul(c, d)) if a == c => Mul(a, Add(b, d))
case _ => a
}
An
Expr
describes a simple structure for algebraic expressions. Generally, a typeExpr[A]
indicates thatA
has some structure that mirrorsExpr
. To get at this symmetry, you must use the type classCoexpr[A]
. This let's us switch between typesA
andExpr[A]
, giving us the ability to extract structure from a typeA
, traverse, and construct the expression tree ofA
, without having to deal withA
as a concrete type.Using
Coexpr
let's us provide further general constructors and pattern matchers. These are defined as the same name as the case class, but without theExpr
appended. So, we can, for example, pattern match on an instancea
of the generic typeA
. Suppose we wanted to map patterns like ab + ac to a(b + c), then we could do the following:a match { case Add(Mul(a, b), Mul(c, d)) if a == c => Mul(a, Add(b, d)) case _ => a }