Frage

ich wundere mich warum scala.Option hat keine Methode fold So definiert:

fold(ifSome: A => B , ifNone: => B)

gleichwertig

map(ifSome).getOrElse(ifNone)

Gibt es nicht besser als zu verwenden map + getOrElse?

War es hilfreich?

Lösung

Du kannst tun:

opt foldLeft (els) ((x, y) => fun(x))

oder

(els /: opt) ((x,y) => fun(x))

(Beide Lösungen werden bewertet els nach Wert, was nicht das ist, was Sie wollen. Dank an Rex Kerr zum Hinweis darauf.)

Bearbeiten:

Aber was Sie wirklich wollen, ist Scalaz's Katamorphismus cata (Grundsätzlich a fold was nicht nur das behandelt Some Wert, aber auch die None Teil, was Sie beschrieben haben)

opt.cata(fun, els)

definiert als (wo value ist der pimped Optionswert)

def cata[X](some: A => X, none: => X): X = value match {
  case None => none
  case Some(a) => some(a)
}

das entspricht zu opt.map(some).getOrElse(none).

Obwohl ich bemerken sollte, dass Sie Cata nur dann verwenden sollten, wenn es die „natürlichere“ Art ist, es auszudrücken. Es gibt viele Fälle, in denen einfach mapgetOrElse reicht vor, insbesondere wenn es darum geht, viele viel zu verketten maps. (Obwohl Sie auch die ketten können funs mit Funktionszusammensetzung natürlich - es hängt davon ab, ob Sie sich auf die Funktionszusammensetzung oder die Werttransformation konzentrieren möchten.)

Andere Tipps

Ich persönlich finde Methoden wie cata Das dauert zwei Schließungen, da Argumente es oft übertreiben. Gewinnen Sie wirklich in der Lesbarkeit map + getOrElse? Denken Sie an einen Neuankömmling Ihres Code: Woraus werden sie machen

opt cata { x => x + 1, 0 }

Denken Sie wirklich, dass dies klarer ist als

opt map { x => x + 1 } getOrElse 0

Tatsächlich würde ich argumentieren, dass keiner gegenüber dem guten Alten vorzuziehen ist

opt match {
  case Some(x) => x + 1
  case None => 0
}

Wie immer gibt es eine Grenze, bei der zusätzliche Abstraktion keine Vorteile bietet und kontraproduktiv wird.

Es wurde schließlich hinzugefügt in Scala 2.10, mit der Unterschrift fold[B](ifEmpty: => B)(f: A => B): B.

Leider hat dies eine gemeinsame negative Folge: B wird für Anrufe abgeleitet, die nur auf dem basieren ifEmpty Argument, das in der Praxis oft enger ist. EG (eine korrekte Version befindet sich bereits in der Standardbibliothek. Dies dient nur zur Demonstration)

 def toList[A](x: Option[A]) = x.fold(Nil)(_ :: Nil)

Scala wird schließen B sein Nil.type statt gewünscht List[A] und beschweren sich über f nicht zurückkehren Nil.type. Stattdessen brauchen Sie einen von

 x.fold[List[A]](Nil)(_ :: Nil)
 x.fold(Nil: List[A])(_ :: Nil)

Das macht fold Nicht ganz entsprechend entsprechend match.

Wie von Debilski erwähnt, können Sie Scalaz's verwenden OptionW.cata oder fold. Wie Jason kommentierte, machen benannte Parameter dies gut:

opt.fold { ifSome = _ + 1, ifNone = 0 }

Nun, wenn der Wert, den Sie in der gewünscht haben None Fall ist mzero für einige Monoid[M] Und Sie haben eine Funktion f: A => M für die Some Fall können Sie dies tun:

opt foldMap f

So,

opt map (_ + 1) getOrElse 0

wird

opt foldMap (_ + 1)

Ich persönlich denke Option sollte eine haben apply Methode, die der Katamorphismus wäre. Auf diese Weise könnten Sie das einfach tun:

opt { _ + 1, 0 }

oder

opt { some = _ + 1, none = 0 }

In der Tat wäre dies schön für alle algebraischen Datenstrukturen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top