C’è una scala identità funzione?

Se ho qualcosa di simile a un List[Option[A]] e voglio convertirlo in un List[A], il metodo standard è quello di utilizzare flatMap:

scala> val l = List(Some("Hello"), None, Some("World"))
l: List[Option[java.lang.String]] = List(Some(Hello), None, Some(World))

scala> l.flatMap( o => o)
res0: List[java.lang.String] = List(Hello, World)

Ora o => o è solo una identità di funzione. Avrei pensato che ci sarebbe stata qualche modo a che fare:

l.flatMap(Identity) //return a List[String]

Tuttavia, non riesco a farlo funzionare, in quanto non è possibile generify un object. Ho provato un paio di cose inutilmente; qualcuno ha ottenuto qualcosa di simile a questo lavoro?

  • Mi piacerebbe pensare che {_} dovrebbe corrispondere a {x => x} come {_ + 3} equivale a {x => x+3}. Chiunque può commentare perché non è così?

 

3 Replies
  1. 59

    C’è un’identità funzione in Predef.

    l flatMap identity[Option[String]]
    
    > List[String] = List(Hello, World)

    Una per expresion è più bello, suppongo:

    for(x <- l; y <- x) yield y

    Edit:

    Ho cercato di capire perché il parametro type (Opzione[String]) è necessario. Sembra che il problema sia il tipo di conversione da l’Opzione[T] per Iterable[T].

    Se si definisce l’identità di funzione:

    l.flatMap( x => Option.option2Iterable(identity(x)))

    il tipo di parametro può essere omesso.

    • Come mai il tipo inferencer non riesco a capire i tipi di per sé? Perché non l.flatMap(identity): List[String] lavoro?
    • Ho pensato che il inferencer potrebbe capire che fuori. Non ho idea. Vorrei aggiungere una domanda. 🙂
    • Vedere modifica. È collegato con le conversioni di tipo implicito.
    • grazie. Peccato per l’identità/Opzione/Iterable cosa come sembra che questo è uno dei principali luoghi in cui è probabile per essere utilizzato. Purtroppo è meno leggibile con identità che senza
    • Questa soluzione non sembra funzionare in scala 2.9.1. l flatMap identity[Option[String]] <console>:9: error: polymorphic expression cannot be instantiated to expected type; found : Option[String] => Option[String] required: Option[java.lang.String] => scala.collection.GenTraversableOnce[?] l flatMap identity[Option[String]] ^
  2. 22

    FWIW, su Scala 2.8 basta chiamare flatten su di esso. Thomas è in gran parte coperto per Scala 2.7. Ha perso solo una modalità alternativa di utilizzare l’identità:

    l.flatMap[String](identity)

    Non funziona con l’operatore notazione, tuttavia (sembra operatore notazione non accetta parametri di tipo, che è bene sapere).

    È possibile anche chiamata flatten su Scala 2.7 (su un List, almeno), ma non sarà in grado di fare nulla senza un tipo. Tuttavia, questo funziona:

    l.flatten[String]
  3. 2

    Si può solo dare il tipo di inferencer un po ‘ di aiuto,

    scala> val l = List(Some("Hello"), None, Some("World"))
    l: List[Option[java.lang.String]] = List(Some(Hello), None, Some(World))
    
    scala> l.flatten[String]
    res0: List[String] = List(Hello, World)

Lascia un commento