2013-07-02 3 views
24

nehme ich diese monadischen Klasse:New Entzuckern Verhalten in 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) 
    } 
} 

Das Folgende ist aus einer 2.10.0 REPL Sitzung:

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

Und hier ist die gleiche Sache in 2.10 0,1:

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

Dies ist völlig unerwartet (für mich), und führt zu einer besonders verwirrend Fehler in Fällen, in denen Filter requ gibt zusätzliche Einschränkungen (wie Scalaz \/ or EitherT).

Ich konnte keine Diskussion über diese Änderung in der 2.10.1 release notes finden. Kann jemand darauf hinweisen, wo und warum dieses neue Entzuckerungsverhalten eingeführt wurde?

Antwort

16

Die Geschichte ist komplexer als das, und es ist in der Tat eine 2.10.0 Regression, die dort gesteckt wurde.

Die „no-withFilter“ Verhalten wurde in c82ecab eingeführt und wegen der Dinge wie SI-6968, diese teilweise #1893 rückgängig gemacht wurde. Weitere Anpassungen folgte (SI-6646, SI-7183)

Das Essen zum Mitnehmen Satz Sie suchen ist:

Der Parser kann nicht davon ausgehen, dass ein Muster (a, b) wird übereinstimmen, wie Ergebnisse von. isInstanceOf [Tuple2] kann erst nach dem Typ statisch erkannt werden.