2013-07-02 9 views
24

Supponiamo che io ho questa classe monadica:Nuovo comportamento Dezuccheraggio a Scala 2.10.1

case class Foo[A](xs: List[A]) { 
    def map[B](f: A => B) = Foo(xs map f) 
    def flatMap[B](f: A => Foo[B]) = Foo(xs flatMap f.andThen(_.xs)) 
    def withFilter(p: A => Boolean) = { 
    println("Filtering!") 
    Foo(xs filter p) 
    } 
} 

Il seguente è da una sessione 2.10.0 REPL:

scala> for { (a, b) <- Foo(List(1 -> "x")) } yield a 
res0: Foo[Int] = Foo(List(1)) 

Ed ecco la stessa cosa in 2.10 .1:

scala> for { (a, b) <- Foo(List(1 -> "x")) } yield a 
Filtering! 
res0: Foo[Int] = Foo(List(1)) 

Questo è del tutto inaspettato (per me), e porta a errori di particolare confusione nei casi in cui il filtraggio requ ulteriori vincoli (come Scalaz \/ or EitherT).

Non è stato possibile trovare alcuna discussione su questo cambiamento nello 2.10.1 release notes. Qualcuno può indicare dove e perché è stato introdotto questo nuovo comportamento di desugaring?

risposta

16

La storia è più complessa di quella, ed è in realtà una regressione 2.10.0 che è stata inserita lì.

Il "no-withFilter" il comportamento è stato introdotto nel c82ecab, ed a causa di cose come SI-6968, questo è stato ripristinato parzialmente #1893. Ulteriori adattamenti seguirono (SI-6646, SI-7183)

La frase da asporto che stai cercando è:

Il parser non può supporre che un modello (a, b) corrisponderà, come risulta di. isInstanceOf [Tuple2] non può essere conosciuto staticamente fino a dopo lo typer.