2012-03-18 10 views
8

Vamos a declarar una definición y una función equivalente como val:Métodos y contra la función implícitos en Scala

scala> def optional(x:Int):Option[String] = None 
optional: (x: Int)Option[String] 

scala> val optional2:(Int)=>Option[String] = (i:Int) => None 
optional2: Int => Option[String] = <function1> 

Ahora por qué no funciona?

scala> List(1).flatMap(optional2) 
<console>:9: error: type mismatch; 
found : Int => Option[String] 
required: Int => scala.collection.GenTraversableOnce[?] 
       List(1).flatMap(optional2) 
          ^

Mientras que ambos hacen?

scala> List(1).flatMap(optional) 
res4: List[String] = List() 

scala> List(1).flatMap(optional2(_)) 
res5: List[String] = List() 

Dado que la opción no es un subtipo de GenTraversableOnce, creo que esto debe tener algo que ver con la implícitos, pero no puedo averiguar qué es exactamente lo que es. Estoy usando Scala 2.9.1.

Respuesta

7

La conversión implícita Option.option2Iterable es lo que hace que List(1).flatMap(optional) y List(1).flatMap(optional2(_)) funcionen.

Su problema puede reducirse a la conversión implícita no ser recogido:

scala> val optional2:(Int)=>Option[String] = (i:Int) => None 
optional2: Int => Option[String] = <function1> 

scala> (optional2(_)): Function[Int, Iterable[String]] 
res0: Int => Iterable[String] = <function1> 

scala> (optional2): Function[Int, Iterable[String]] 
<console>:9: error: type mismatch; 
found : Int => Option[String] 
required: Int => Iterable[String] 

Cuando se utiliza el subrayado, el compilador intenta escribir la función y proporcionar la necesaria conversión implícita. Cuando acaba de proporcionar optional2, no se aplica ninguna conversión implícita.

+0

sí, pero ¿por qué no se puede aplicar en el primer caso? –

+0

@KimStebel, no hay conversión implícita para 'optional2'. En el segundo caso 'optional2 (_)', el compilador crea una función para usted e intenta hacer coincidir el tipo de devolución y es cuando elige 'option2Iterable'. – huynhjl

+3

En otras palabras, no hay conversión implícita de 'Función [T, R1] => Función [T, R2]' donde existe un 'R1 => R2' implícito. Necesita construir un nuevo objeto de función con 'optional2 (_)' para que pueda ocurrir la conversión implícita, en este caso 'i => optional2 (i: Iterable [String])'. 'optional2' es un objeto,' optional2 (_) 'es uno nuevo. –

Cuestiones relacionadas