Ich habe den grundlegenden Unterschied zwischen foldLeft
und gelerntreduceLeft
foldLeft:
- Anfangswert muss übergeben werden
reduziere:
- Nimmt das erste Element der Sammlung als Anfangswert
- löst eine Ausnahme aus, wenn die Sammlung leer ist
Gibt es noch einen anderen Unterschied?
Gibt es einen bestimmten Grund für zwei Methoden mit ähnlicher Funktionalität?
scala
functional-programming
fold
higher-order-functions
Rajesh Pitty
quelle
quelle
Antworten:
Einige Dinge, die hier zu erwähnen sind, bevor die eigentliche Antwort gegeben wird:
left
, es geht vielmehr um den Unterschied zwischen Reduzieren und FaltenZurück zu Ihrer Frage:
Hier ist die Unterschrift von
foldLeft
(könnte auchfoldRight
für den Punkt gewesen sein, den ich machen werde):Und hier ist die Unterschrift von
reduceLeft
(auch hier spielt die Richtung keine Rolle)Diese beiden sehen sich sehr ähnlich und haben somit die Verwirrung verursacht.
reduceLeft
ist ein Sonderfall vonfoldLeft
(was übrigens bedeutet, dass Sie manchmal dasselbe ausdrücken können, indem Sie einen von beiden verwenden).Wenn Sie
reduceLeft
say on a aufrufen ,List[Int]
wird die gesamte Liste der Ganzzahlen buchstäblich auf einen einzigen Wert reduziert, der vom TypInt
(oderInt
daher vom Supertyp von[B >: A]
) sein wird.Wenn Sie
foldLeft
say on a aufrufen ,List[Int]
wird die gesamte Liste (stellen Sie sich vor, Sie rollen ein Stück Papier) zu einem einzigen Wert zusammengefasst, aber dieser Wert muss nicht einmal mitInt
(daher[B]
) verknüpft sein .Hier ist ein Beispiel:
Diese Methode nimmt ein
List[Int]
und gibt einTuple2[List[Int], Int]
oder zurück(List[Int], Int)
. Es berechnet die Summe und gibt ein Tupel mit einer Liste von ganzen Zahlen und seiner Summe zurück. Übrigens wird die Liste rückwärts zurückgegeben, weil wirfoldLeft
statt verwendet habenfoldRight
.Beobachten Sie One Fold, um sie alle zu regieren und eine ausführlichere Erklärung zu erhalten.
quelle
B
ein Supertyp von istA
? Es scheint, alsB
sollte es sich tatsächlich um einen Subtyp handelnA
, nicht um einen Supertyp. AngenommenBanana <: Fruit <: Food
, wenn wir eine Liste vonFruit
s hätten, könnte diese einigeBanana
s enthalten , aber wenn sieFood
s enthalten würdeFood
, wäre der Typ richtig? In diesem Fall sollte die Liste vom Typ sein , wennB
es sich um einen Supertyp von handeltA
und es eine Liste gibt, die sowohlB
s als auchA
s enthält . Können Sie diese Diskrepanz erklären?B
A
List[Banana]
auf eine einzelneBanana
oder eine einzelneFruit
oder eine einzelne reduziert werden kannFood
. WeilFruit :> Banana
und `Essen:> Banane '.Banana
kann ein enthaltenFruit
" interpretiert , was keinen Sinn ergibt. Ihre Erklärung ist sinnvoll - dief
Funktion, an die übergeben wird,reduce()
kann zu aFruit
oder a führenFood
, was bedeutet, dassB
die Signatur eine Oberklasse und keine Unterklasse sein sollte.reduceLeft
ist nur eine bequeme Methode. Es ist äquivalent zuquelle
reducelft
obwohlfold
eine leere Listereduce
nicht funktioniert.foldLeft
ist allgemeiner, Sie können es verwenden, um etwas völlig anderes als das zu produzieren, was Sie ursprünglich eingegeben haben. WährendreduceLeft
nur ein Endergebnis des gleichen Typs oder Supertyps des Sammlungstyps erzeugt werden kann. Beispielsweise:Das
foldLeft
wird den Verschluss mit dem zuletzt gefalteten Ergebnis (zum ersten Mal unter Verwendung des Anfangswertes) und dem nächsten Wert anwenden.reduceLeft
Auf der anderen Seite werden zuerst zwei Werte aus der Liste kombiniert und diese auf den Abschluss angewendet. Als nächstes werden die restlichen Werte mit dem kumulativen Ergebnis kombiniert. Sehen:Wenn die Liste leer ist,
foldLeft
kann der Anfangswert als rechtliches Ergebnis angezeigt werden.reduceLeft
Auf der anderen Seite hat es keinen legalen Wert, wenn es nicht mindestens einen Wert in der Liste finden kann.quelle
Der Hauptgrund, warum sie sich beide in der Scala-Standardbibliothek befinden, ist wahrscheinlich, dass sie sich beide in der Haskell-Standardbibliothek befinden (aufgerufen
foldl
undfoldl1
). Wenn diesreduceLeft
nicht der Fall wäre, würde es in verschiedenen Projekten häufig als praktische Methode definiert.quelle
Als Referenz
reduceLeft
wird ein Fehler auftreten, wenn er auf einen leeren Container mit dem folgenden Fehler angewendet wird.Überarbeitung des zu verwendenden Codes
ist eine mögliche Option. Eine andere Möglichkeit besteht darin, die
reduceLeftOption
Variante zu verwenden, die ein mit Option umschlossenes Ergebnis zurückgibt.quelle
Aus funktionalen Programmierprinzipien in Scala (Martin Odersky):
[im Gegensatz zu
reduceLeft
, was eine Ausnahme auslöst, wenn es auf einer leeren Liste aufgerufen wird.]Der Kurs (siehe Vorlesung 5.5) enthält abstrakte Definitionen dieser Funktionen, die ihre Unterschiede veranschaulichen, obwohl sie sich in der Verwendung von Mustervergleich und Rekursion sehr ähnlich sind.
Beachten Sie, dass
foldLeft
ein Wert vom Typ zurückgegeben wirdU
, der nicht unbedingt vom selben Typ ist wieList[T]
, aber reduLeft einen Wert vom selben Typ wie die Liste zurückgibt.quelle
Um wirklich zu verstehen, was Sie mit Fold / Reduce machen, überprüfen Sie dies: http://wiki.tcl.tk/17983 sehr gute Erklärung. Sobald Sie das Konzept der Falte erhalten haben, wird Reduzieren zusammen mit der obigen Antwort angezeigt: list.tail.foldLeft (list.head) (_)
quelle