12 Stimmen

Scala: wie versteht man die flatMap-Methode von Try?

Die flatMap-Methode des Success wird wie folgt implementiert:

  def flatMap[U](f: T => Try[U]): Try[U] =
    try f(value)
    catch {
      case NonFatal(e) => Failure(e)
    }

Ich verstehe irgendwie, was diese Methode macht, sie hilft uns, eine Menge an Code zum Fangen von Fehlern zu vermeiden.

Aber inwiefern ähnelt sie dem regulären flatMap?

Ein regulärer flatMap nimmt eine Sequenz von Sequenzen und fügt alle Elemente in eine große "flache" Sequenz ein.

Aber die flatMap-Methode von Try flattet eigentlich nichts.

Also, wie versteht man die flatMap-Methode von Try?

11voto

maasg Punkte 36494

Ohne in Monaden einzusteigen, anstatt darüber in Bezug auf Sammlungen nachzudenken, könnten Sie stattdessen in Bezug auf Strukturen darüber nachdenken (wo eine Sammlung zu einer Struktur mit vielen Einträgen wird).

Schauen Sie sich jetzt die Signatur von Try.flatmap (aus Ihrem Beitrag) an:

def flatMap[U](f: T => Try[U]): Try[U] die Funktion f transformiert T in ein Try[U] im Kontext von Try[T].

Stellen Sie sich dagegen vor, die Operation wäre 'map', das Ergebnis wäre:

def badMap[U](f: T => Try[U]): Try[Try[U]]

Wie Sie sehen können, 'flattening' flatmap das Ergebnis in den Kontext von Try[T] und produziert Try[U] anstelle des verschachtelten Try[Try[U]].

Sie können dasselbe Konzept des 'Abflachens von verschachtelten Strukturen' auf Sammlungen anwenden, wie von Ihnen erwähnt.

5voto

Shyamendra Solanki Punkte 8673

Sie können Try[T] als ähnlich zu einer Sammlung von nur einem Element (wie Option[T]) betrachten.

Wenn die "Sequenz von Sequenzen" "nur eine Sequenz" ist, sind map und flatmap fast ähnlich. Der einzige Unterschied besteht in der Signatur der Funktion.

In diesem Fall ist keine Abflachung erforderlich.

2voto

Ed Staub Punkte 15126

Ich fand Dan Spiewaks "Monads Are Not Metaphors" sehr hilfreich, um mich mit Monaden vertraut zu machen. Für Leute, die wie ich mit Scala anfangen, ist es viel einfacher zu verstehen als alles andere, was ich gefunden habe - einschließlich Oderskys Schriften. Achten Sie beim Lesen darauf, dass 'bind'=='flatMap'.

1voto

Piotr Kukielka Punkte 3722

Wie Sie in Ein Rundgang durch Scala: Sequenz-Verständnis lesen können: "In Scala kann jeder Datentyp, der die Operationen filter, map und flatMap (mit den richtigen Typen) unterstützt, in Sequenz-Verständnissen verwendet werden." Tatsächlich bedeutet dies, dass Sie es wie ein Monad behandeln können.
Und flatMap für einen Monad hat eine Signatur wie diese:

def flatMap(f: A => M[B]): M[B]

Alle Sammlungen in Scala haben monadische Schnittstellen, sodass Sie monadische Operationen in diesem engen Rahmen als Operationen auf Sequenzen betrachten können. Aber das ist nicht die ganze Geschichte. Im Fall einiger Monaden ist es verwirrender als hilfreich, sie als Sammlungen zu betrachten. Im Allgemeinen wendet flatMap eine Transformation des "Inhalts" eines Mondes an, indem dieser Mond mit einer Operation komponiert wird, die in einer anderen Mondinstanz desselben Typs resultiert. Daher können Sie Monaden auf mindestens zwei Arten betrachten:

  • Monad ist eine Art Sammlung (oder Box, die etwas hält) und die Elemente dieser Sammlung sind der "Inhalt".
  • Monad ist eine Art Kontext und die Elemente des Monads sind einfach einige Berechnungen, die in diesem Kontext durchgeführt werden.

Manchmal ist es einfacher, über eine Monade als eine Sammlung nachzudenken, manchmal ist es einfacher, sie als Kontext zu betrachten. Zumindest für mich. Tatsächlich sind beide Ansätze austauschbar, d.h. Sie können Listen (Sammlungen) als nichtdeterministische Berechnungen betrachten, die eine beliebige Anzahl von Ergebnissen zurückgeben können.

Also im Fall von Try könnte es einfacher sein, darüber als Ausführungskontext nachzudenken, mit zwei Zuständen, Erfolg und Misserfolg. Wenn Sie mehrere Versuche komponieren möchten und einer von ihnen sich im Misserfolgszustand befindet, wird der gesamte Kontext zum Misserfolg (die Kette wird unterbrochen). Andernfalls können Sie einige Operationen am "Inhalt" dieser Versuche durchführen und der Kontext ist erfolgreich.

1voto

Glen Best Punkte 22041

Ein regulärer flatMap nimmt eine Sequenz von Sequenzen und setzt alle Elemente in eine große "flache" Sequenz.

Leichte Korrektur:

Ein regulärer flatMap nimmt eine Sequenz (allgemeiner Monade), hat ein Argument, das eine Funktion ist, die ein Element in eine Sequenz (Monade) umwandelt, und gibt eine "flache" Sequenz (Monade) zurück.

Zum Vergleich die detaillierten Unterschritte hier :). Die flatmap-Methode iteriert über die Eingabesequenz und ruft f(element) auf, erstellt jedoch eine einzelne neue Ergebnissequenz. Der "flatten"-Teil wird nach jeder Funktion-Argument-Anwendung f(element) angewendet, es wird eine verschachtelte Iteration über die resultierende Teile-Sequenz durchgeführt und jeder Eintrag in der einzelnen Ergebnissequenz ausgegeben.

Das Äquivalent für Success, mit einem value darin (allgemeiner eine Monade):

  • flatmap hat ein Argument, das eine Funktion ist, die Success in Try = Success(value) ODER Failure(exception) umwandelt. Nach Anwendung von f(value) handelt es sich bereits um ein Try. Der "flatten"-Teil ist eine triviale/Null-Operation: Eine Iteration über das Funktionsergebnis würde nur einen Eintrag liefern, daher müssen Try/Success/Failure nicht einmal Iterable implementieren). Es werden keine zusätzlichen Schichten von Success/Failure umschlossen und somit wird ein "flacher" Try zurückgegeben.

    D.h. Der "flache" Teil bedeutet, dass keine Success/Failure-Umschließungen aufeinander folgen, genauso wie ein Sequenz-flatmap keine Sequenzen in einer (Wertbaum-)Hierarchie kaskadiert.

  • Dies unterscheidet sich von map, dessen Argument eine Funktion ist, die Success in einen beliebigen Typ U konvertiert; nach Anwendung von f(value) muss map eine zusätzliche Schicht neuer Success/Failure-Umhüllung um den value/exception hinzufügen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X