Il giorno domenica 7 ottobre 2012 20:52:08 UTC+2, Paul Phillips ha scritto:
On Sun, Oct 7, 2012 at 11:29 AM, Jon Pretty
<googl...@accounts.propensive.com> wrote:
Defining lots of extractors called "AsInt", "AsDouble", "AsFoo" doesn't appeal to me nearly as much as defining just one called "As". How hard would it be to support this?
It is long desired; all the way to 884.
Upvoted as well.
It may not be enormously difficult now that we have virtpatmat.
Do you mean "we can use virtualization" or just "the code is well-written, so I can change it without hell breaking loose"?
While at it or independently, would it be possible to support this code better?
case class Eq[T](a: T, b: T)
//... foo match {
case x: Eq[u] =>
x match {
case Eq(a, b) => ...
}
Possible syntaxes:
case Eq[u](a, b) => //hopefully allowed by fixing SI-884?
But more in general, it'd be nice to support nesting patterns inside type patterns. At least, it'd allow
case Eq(a, b): Eq[u] =>
even though this might be less useful when case Eq[u](a, b) is supported.
Consider this example:
case class Eq[T](a: T, b: T)
class EqString(a: String, b: String) extends Eq[String](a, b)
I can't write this:
def f[T]: Eq[T] => Eq[T] = {
case Eq(a, b): EqString => Eq("a", "b" + b.charAt(0))
}
Nor could I write:
def f[T]: Eq[T] => Eq[T] = {
case Eq[String](a, b) => Eq("a", "b" + b.charAt(0))
}
because String is unchecked there, so the call to charAt would fail when passing
Instead, I need to write this:
def f[T]: Eq[T] => Eq[T] = {
case bound: EqString => Eq("a", "b" + bound.b.charAt(0))
}
Of course I can call extractors after the match, and match on them, and then match on their subterms, and so on, but the point of nested pattern matching is to avoid that. Look just at the pattern matches below:
val mergeMapsSimplified = new Transformer {
def apply[T](e: Exp[T]) = e match {
case Sym(m: MapNode[t, repr, u, that]) => //T = that
m.base match {
case Sym(m2: MapNode[t2, repr2, u2, that2]) =>
(((m2.base map m2.f)(m2.c): Exp[repr with TraversableLike[t, repr]]) map m.f)(m.c) //works
case _ => e
}
case _ => e
}
}
The above pattern matches should be mergeable in a single nested one.
You might wonder "But why the heck all those type annotations?" Because there I was trying to make map fusion _type-safe_. Yet, all that is just needed to rewrite a representation of `e map f map g` to another representation of the same expression. I stopped there because I'd need to make the compiler figure out that t >: u2, which seems hard in my scenario.