Um zu verstehen, wie dies funktioniert, kann es nützlich sein, die Funktionen explizit zu entpacken, die Sie an map
und flatMap
senden und ihre Signaturen untersuchen. Ich habe sie hier umgeschrieben, so dass Sie sehen können, dass f
eine Funktionszuordnung von Int
zu einem (Int, Int)
Tupel ist und g
eine Funktion ist, die von Int
auf eine List[Int]
abbildet.
val f: (Int) => (Int, Int) = x => (x*2, x*3)
val g: (Int) => List[Int] = x => List(x*2, x*3)
List(1,2,3).map(f)
//res0: List[(Int, Int)] = List((2,3), (4,6), (6,9))
List(1,2,3).map(g)
//res1: List[List[Int]] = List(List(2, 3), List(4, 6), List(6, 9))
//List(1,2,3).flatMap(f) // This won't compile
List(1,2,3).flatMap(g)
//res2: List[Int] = List(2, 3, 4, 6, 6, 9)
Also warum wird flatMap(f)
nicht kompilieren? Lassen Sie sich für flatMap
, in diesem Fall auf der Unterschrift sieht von der List
Implementierung gezogen:
final override def flatMap[B, That](f : scala.Function1[A, scala.collection.GenTraversableOnce[B]])(...)
Dies ist ein wenig schwierig zu entpacken, und ich habe einige davon elided, aber der Schlüssel ist der GenTraversableOnce
Typ. List
, wenn Sie seine Kette der Vererbung nach oben folgen, hat dies eine Eigenschaft, mit der es gebaut wird, und damit eine Funktion, die von einem Typ A
zu einem List
(oder einem Objekt mit der GenTraversableOnce
Trait) abbildet wird eine gültige Funktion sein. Bemerkenswerterweise haben Tupel diese Eigenschaft nicht.
Dies ist die In-the-Unkraut-Erklärung, warum die Eingabe falsch ist, und ist erklärungswürdig, weil jeder Fehler, der besagt, kann nicht mit einer solchen Signatur auflösen 'bedeutet, dass es keine Funktion finden kann, die die explizite nimmt Geben Sie an, was Sie anbieten. In Scala werden sehr oft Typen abgeleitet, sodass Sie sicherstellen können, dass der von Ihnen angegebene Typ der Typ ist, der von der aufgerufenen Methode erwartet wird.
Beachten Sie, dass flatMap
eine Standardbedeutung in der funktionalen Programmierung hat, was grob gesagt jede Zuordnungsfunktion ist, die ein einzelnes Element konsumiert und n Elemente erzeugt, aber Ihr Endergebnis ist die Verkettung all dieser Listen.Daher wird von der Funktion, die Sie an flatMap
übergeben, immer erwartet, dass eine Liste erstellt wird, und es wird erwartet, dass die Funktion flatMap
nicht weiß, wie sie auf einzelne Elemente einwirken soll.
Was ist die Art von 'Eingang'? Überprüfen Sie die map- und flatMap-Methodensignaturen. Es hat verschiedene Parameter, deshalb hat Ihr Code einen Kompilierungsfehler. –
Weil 'flatMap' zum Abflachen der Struktur verwendet wird. Wenn Sie ein 'M [M [A]]' mit 'map' erhalten, erhalten Sie' M [A] 'mit' flatMap'. –
Das verschachtelte 'M' kann manchmal anders sein,' N' .. Zum Beispiel 'List [Option [String]]' => 'List [String]' –