2011-11-29 4 views
10

Obtengo un comportamiento diferente en 2.9.1 y 2.10 cada noche, ¿qué cambió?Diferencia al aplanar una opción [Lista [Int]] en 2.9.1 y 2.10 cada noche

Welcome to Scala version 2.9.1.final (OpenJDK Client VM, Java 1.6.0_22). 
Type in expressions to have them evaluated. 
Type :help for more information. 

scala> Some(3) map (x => List(x, -x)) flatten 
res0: List[Int] = List(3, -3) 

Versus:

Welcome to Scala version 2.10.0.r26084-b20111129020255 (OpenJDK Client VM, Java 1.6.0_22). 
Type in expressions to have them evaluated. 
Type :help for more information. 

scala> Some(3) map (x => List(x, -x)) flatten 
<console>:8: error: Cannot prove that List[Int] <:< Option[B]. 
       Some(3) map (x => List(x, -x)) flatten 

Respuesta

16

La razón es que la opción adquirió un método flatten en 2.10, que sólo funciona en anidados Option s.

En 2,9, se añadió la llamada para aplanar por una conversión implícita a Iterable, y el resultado fue un Iterable (o un subtipo de la misma, en función del valor anidada dentro Option).

Aquí está la firma del flatten en 2.10:

def flatten[B](implicit ev: <:<[A, Option[B]): Option[B] 

Se dice: si se puede encontrar evidencia de que el elemento dentro de esta opción es una Option sí, dicen Option[B], puedo aplanar eso y devolver un Option[B].

Los implicitos solo se prueban si hay no método con ese nombre, por lo que esto explica por qué no se recurre al método 2.9.

+0

Parece que este nuevo 'aplanar' está más en línea con el' unirse' monádico de Haskell; es esa la intención? –

+0

¡Esperemos que todos realicen pruebas de regresión completas cuando actualicen a 2.10! –

+0

Definitivamente una mejora que la Opción [Opción [X]] puede aplanar a la Opción [X], aunque es un poco desagradable el caso Iterable. Supongo que una aplanadora más flexible podría juntarse con un poco de maquinaria de clase, si realmente la querías tan mal ... –