2014-10-17 13 views
5

Ich bin sicher, dass es einen guten Grund dafür gibt, aber ich sehe es nicht.Option.fold - Warum ist das zweite Argument kein binärer Operator?

Fold auf (sagen wir) List kehrt

das Ergebnis der Anwendung fold Operator op zwischen allen Elementen und z

Es hat eine offensichtliche Beziehung zu foldLeft und foldRight, die das gleiche tun aber mit definierter Reihenfolge (und benötigen daher keine assoziativen Operatoren)

Fold auf Option kehrt

Gibt das Ergebnis f diese scala.Option ‚s Wert anzuwenden, wenn die scala.Option nicht leer ist. Andernfalls wird der Ausdruck ifEmpty ausgewertet.

ifEmpty ist (in der Position der) z für eine Liste. f ist (in der Position) die op

Für None (die mein mentales Modell von Option als „Container“ verwenden, die keinen Wert enthalten können oder nicht, ein „leerer“ Container ist), sind die Dinge in Ordnung , Option.fold gibt die Null zurück (Wert ifEmpty).

Für Some(x) allerdings sollte f nicht zwei params nehmen, z und x so ist es mit dem fold auf Sequenzen konsistent (einschließlich eine ähnliche Beziehung zu foldLeft mit und foldRight).

Es gibt definitiv ein Dienstprogramm Argument dagegen - mit f nehmen Sie einfach x als Parameter in der Praxis wahrscheinlich bequemer. In den meisten Fällen, wenn es auch z brauchte, würde das ignoriert werden. Aber Konsistenz ist auch wichtig ...

Also kann mir jemand erklären warum fold auf Option ist immer noch eine "richtige" fold?

+0

Aber 'Einige # falten' braucht 2 Argumente. https://github.com/scala/scala/blob/v2.11.3/src/library/scala/Option.scala#L1 Es tut mir leid, ich verstehe die Frage nicht – Jatin

+0

Es braucht tatsächlich zwei Argumente; aber die Argumente sind nur in separaten Argumentlisten. – Jesper

+0

Ich frage, warum das zweite Argument kein binärer Operator ist. Nicht warum fold selbst zwei Argumente braucht - wie Sie sagen, tut es! –

Antwort

2

Warum sollte es sein?

Der Grund, warum "normal" einen binären Operator benötigt, ist, weil "normal" über eine Liste verwendet wird, die einzeln mit binären Operatoren (und dem Seed-Wert z) verarbeitet werden kann.

Falten auf einer Option ist de facto eine Kartenfunktion mit einem Standardfall. Wenn Sie bei der Definition aussehen, es ist buchstäblich:

if (isEmpty) ifEmpty else f(this.get) 

Da Sie nur ein mögliches Argument haben, hat f ein unärer Operator sein. Man könnte argumentieren, dass eine Option falten könnte, die einen binären Operator verwendet und den ifEmpty-Wert als Seed verwendet, falls die Option definiert ist, aber Ihr vernünftiger Seed-Wert und Ihr vernünftiger Wert für den Fall, dass die Option leer ist, können sehr unterschiedlich sein.

Wie bereits erwähnt, benötigen Sie für verschiedene Strukturen unterschiedliche Aritäten (zB für Bäume), weil die "sinnvolle" Anwendung einer Reduktion unterschiedliche Strukturen hat.

0

scala.Option.fold ist ein Fehler; schlechtes API-Design.

Option { 
    // This is equivalent to: map f getOrElse ifEmpty. 
    def fold[B](ifEmpty: => B)(f: A => B): B = if (isEmpty) ifEmpty else f(this.get) 
} 

Die Option.fold Verfahren nützlich sein kann, aber es ist kein fold (ebenfalls für Either.fold).

TraversableOnce { 
    // List, et alia 
    def fold[A1 >: A](z: A1)(op: (A1, A1) => A1): A1 = foldLeft(z)(op) 
} 

Der Nutzen eine Standard-Methode ist, dass das Konzept und die Art Signatur konsistent ist (keine Notwendigkeit, die Dokumente erneut zu überprüfen).

Auch Option.foldLeftist konsistent, und nimmt einen binären Operator.

Verwandte Themen