This page is no longer maintained — Please continue to the home page at www.scala-lang.org

unapply inference, gadts etc.

2 replies
extempore
Joined: 2008-12-17,
User offline. Last seen 35 weeks 3 days ago.

Is there some good reason for this to do this? (This is the real scala
I'm asking about, not virtpatmat.) This is in the category of things
which ought to work, right? The problem is that in real life is that I
can't use unapplyWhichWorks because "Foo" doesn't really have an x
member, it's an empty trait. Bar and Baz are unrelated types except
that they each extends Foo[T]. I need to be able to recover the type
upon which Foo is parameterized, and get the actual "x" via more than
one unrelated method.

trait Foo[+A] {
def x: A
}
case class Bar[+T1](x: T1) extends Foo[T1]
case class Baz[+T1, +T2](x: Tuple2[T1, T2]) extends Foo[Tuple2[T1, T2]]

object Foo {
// this works
def unapplyWhichWorks[T](p: Foo[T]): Option[T] = Some(p.x)

// this demands Option[Any], else:
//
// found : x.type (with underlying type (Any, Any))
// required: T
// case Baz(x) => Some(x)
// ^
def unapply[T](p: Foo[T]) /*: Option[T]*/ = p match {
case Bar(x) => Some(x)
case Baz(x) => Some(x)
case _ => None
}
}

adriaanm
Joined: 2010-02-08,
User offline. Last seen 31 weeks 4 days ago.
Re: unapply inference, gadts etc.
yes, this should work, but GADT type inference is broken
I think the problem is that it's reusing type inference to discover equalities between type variables (as opposed to equalities between type variables and concrete types), but type inference is not set up for that -- I was thinking of using the suspended flag for this,  and have solve treat suspended type vars as type constants
workaround:    case Baz(x: T)   => Some(x)
I'd like to fix GADT type inference at some point, but a complete rewrite is in order I think (unrelated to virtpatmat)
this paper describes the state of the art in GADT inference: http://research.microsoft.com/en-us/um/people/simonpj/papers/constraints/jfp-outsidein.pdf (their untouchable unification variables would correspond to suspended type variables)
On Wed, Sep 21, 2011 at 8:14 PM, Paul Phillips <paulp [at] improving [dot] org> wrote:
Is there some good reason for this to do this? (This is the real scala
I'm asking about, not virtpatmat.) This is in the category of things
which ought to work, right? The problem is that in real life is that I
can't use unapplyWhichWorks because "Foo" doesn't really have an x
member, it's an empty trait.  Bar and Baz are unrelated types except
that they each extends Foo[T].  I need to be able to recover the type
upon which Foo is parameterized, and get the actual "x" via more than
one unrelated method.

trait Foo[+A] {
 def x: A
}
case class Bar[+T1](x: T1) extends Foo[T1]
case class Baz[+T1, +T2](x: Tuple2[T1, T2]) extends Foo[Tuple2[T1, T2]]

object Foo {
 // this works
 def unapplyWhichWorks[T](p: Foo[T]): Option[T] = Some(p.x)

 // this demands Option[Any], else:
 //
 //  found   : x.type (with underlying type (Any, Any))
 //  required: T
 //     case Baz(x)   => Some(x)
 //                           ^
 def unapply[T](p: Foo[T]) /*: Option[T]*/ = p match {
   case Bar(x)   => Some(x)
   case Baz(x)   => Some(x)
   case _        => None
 }
}

extempore
Joined: 2008-12-17,
User offline. Last seen 35 weeks 3 days ago.
Re: unapply inference, gadts etc.

On Thu, Sep 22, 2011 at 2:46 AM, Adriaan Moors wrote:
> workaround:    case Baz(x: T)   => Some(x)

Oh, that's not too shabby. Reminds me we still have no general error
suppression mechanism though. Would really, really like a way to
squash warnings which I cannot eliminate for one reason or another.
The difference between "every time I run the build there are 0
warnings, and this time there is 1" and "every time I run the build
there are 20 warnings, and this time there are 21" is not small.

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland