2012-03-18 18 views
8

Facciamo dichiarare una definizione e una funzione equivalente come val:Metodi rispetto delle funzioni e impliciti in 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> 

Ora, perché non funziona?

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

Mentre entrambi fanno?

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

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

Dal momento che l'opzione non è un sottotipo di GenTraversableOnce, penso che questo deve avere qualcosa a che fare con impliciti, ma non riesco a capire che cosa si tratta esattamente. Sto usando Scala 2.9.1.

risposta

7

La conversione implicita Option.option2Iterable è ciò che fa funzionare List(1).flatMap(optional) e List(1).flatMap(optional2(_)).

Il tuo problema può essere bollito fino alla conversione implicita non essere stati prelevati:

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] 

Quando si utilizza la sottolineatura, il compilatore tenta di digitare la funzione e fornire la necessaria conversione implicita. Quando fornisci semplicemente l'opzione 2, non viene applicata alcuna conversione implicita.

+0

sì, ma perché non può essere applicato nel primo caso? –

+0

@KimStebel, non c'è conversione implicita per 'optional2'. Nel secondo caso, 'opzionale2 (_)', il compilatore crea una funzione per te e cerca di far corrispondere il tipo restituito ed è quando sceglie 'option2Iterable'. – huynhjl

+3

In altre parole, non esiste alcuna conversione implicita da 'Funzione [T, R1] => Funzione [T, R2]' in cui esiste un implicito 'R1 => R2'. È necessario creare un nuovo oggetto funzione con 'optional2 (_)' in modo che possa avvenire la conversione implicita, in questo caso 'i => optional2 (i: Iterable [String])'. 'optional2' è un oggetto,' optional2 (_) 'è uno nuovo. –

Problemi correlati