Ich bin keiner der Autoren von Functional Programming in Scala, aber ich kann ein paar Vermutungen darüber machen, warum sie Try
nicht erwähnen.
Einige Leute mögen nicht die Standardbibliothek Try
, weil sie Anspruch it violates the functor composition law beanspruchen. Ich persönlich denke, dass diese Position irgendwie albern ist, aus den Gründen, die Josh Suereth in den Kommentaren von SI-6284 erwähnt, aber die Debatte hebt einen wichtigen Aspekt von Try
s Design hervor.
Try
's map
und flatMap
sind explizit entworfen, um mit Funktionen zu arbeiten, die Ausnahmen auslösen können. Leute von der FPiS-Denkschule (einschließlich mir) würden dazu neigen, solche Funktionen (wenn Sie absolut mit ihnen fertig werden müssen) in sichere Versionen auf einer niedrigen Ebene in Ihrem Programm einzubinden und dann eine API offenzulegen, die niemals geworfen wird (nicht-tödliche) Ausnahmen.
Einschließlich Try
in Ihrer API verwirren die Ebenen in diesem Modell - Sie garantieren, dass Ihre API-Methoden keine Ausnahmen auslösen, aber dann übergeben Sie Personen einen Typ, der mit Funktionen zum Auslösen von Ausnahmen verwendet werden soll .
Das ist nur eine Beschwerde über das Design und die Implementierung der Standardbibliothek von Try
, obwohl. Es ist einfach, sich eine Version von Try
mit unterschiedlicher Semantik vorzustellen, bei der die Methoden map
und flatMap
keine Ausnahmen abfangen, und es gibt immer noch gute Gründe, diese "verbesserte" Version von Try
wann immer möglich zu vermeiden.
Einer dieser Gründe ist, dass die Verwendung von Either[MyExceptionType, A]
anstelle von Try[A]
es möglich macht, mehr Kilometer aus der Vollständigkeitsprüfung des Compilers zu bekommen. Angenommen, ich bin mit der folgenden einfachen ADT für Fehler in meiner Anwendung:
sealed class FooAppError(message: String) extends Exception(message)
case class InvalidInput(message: String) extends FooAppError(message)
case class MissingField(fieldName: String) extends FooAppError(
s"$fieldName field is missing"
)
Jetzt zu entscheiden Ich versuche, ob ein Verfahren, das kann nur nicht in einer dieser beiden Möglichkeiten sollte Either[FooAppError, A]
oder Try[A]
zurückzukehren. Die Wahl Try[A]
bedeutet, dass wir Informationen wegwerfen, die sowohl für menschliche Benutzer als auch für den Compiler nützlich sein können. Angenommen, ich schreibe eine Methode wie folgt:
def doSomething(result: Either[FooAppError, String]) = result match {
case Right(x) => x
case Left(MissingField(_)) => "bad"
}
Ich werde eine nette Kompilierungswarnung erhalten, die mir sagt, dass das Spiel nicht erschöpfend ist. Wenn ich einen Fall für den fehlenden Fehler hinzufüge, verschwindet die Warnung.
Wenn ich Try[String]
stattdessen verwendet hatte, habe ich auch exhaustivity Kontrolle bekommen würde, aber der einzige Weg, um die Warnung zu befreien wäre, einen zu haben, allumfassende Fall-es ist einfach nicht möglich, alle Throwable
s in der aufzuzählen Muster Match.
Manchmal können wir die Art und Weise, wie ein Vorgang zu unserem eigenen Fehlertyp fehlschlagen kann (wie FooAppError
oben), und in diesen Fällen können wir immer Either[Throwable, A]
verwenden. Beispielsweise ist Scalaz Task
im Wesentlichen eine Umhüllung für Future[Throwable \/ A]
. Der Unterschied ist, dass Either
(oder \/
) unterstützt diese Art von Signatur, während Try
erfordert es. Und es ist nicht immer, was Sie wollen, aus Gründen wie nützliche Überprüfung der Vollständigkeit.
Meine Vermutung ist, dass das Buch geschrieben wurde, bevor Try der Scala-Standardbibliothek hinzugefügt wurde. Try wurde in Version 2.10 hinzugefügt. – marstran
Auf Seite 58 und 61 implementieren sie ihre eigene "Try" -Funktion mit ihren Definitionen von "Option" und "Entweder". _FP in Scala_ ist kein Buch über Scala, sondern über Functional Programming (in Scala), deshalb werden in den Übungen Teile der bestehenden Scala API neu implementiert, um das Konzept von FP zu lernen. –
@marstran 'Try' gibt es seit 2012 und das Buch wurde dieses Jahr veröffentlicht. Wenn "Versuchen" relevant wäre und die Autoren es diskutieren wollten, hätten sie es getan. –