defasString: String

Convert the current object into a string or throw a TypeException if
not possible.

Convert the current object into a string or throw a TypeException if
not possible. Note the difference between this and toString.
asString returns the content, while toString returns a representation
of the primitive value itself.
An overt example of this is:
val temp = StringPrimitive('foo')
println(temp.asString) // Returns "foo"
println(temp.toString) // Returns "'foo'"
Note the extra quotes. If you ever see a problem involving strings
with too many nested quotes, your problem is probably with asString

Perform a recursive rewrite.
The following pattern is pretty common throughout Mimir:
def replaceFooWithBar(e:Expression): Expression =
e match {
case Foo(a, b, c, ...) => Bar(a, b, c, ...)
case _ => e.recur(replaceFooWithBar(_))
}
Note how specific rewrites are applied to specific patterns
in the tree, and recur is used to ignore/descend through
every other class of object