2014-01-17 16 views
8

Mein Verständnis von ein der Unterschiede zwischen Monad und Applicative ist, dass flatMap auf Monad vorhanden ist, aber nicht Applicative.JsResult - Monad oder Applicative?

Wenn das stimmt, ich bin verwirrt durch diese Scala JSON Spielen docs:

Also, was ist interessant, es ist, dass JsResult [A] ist eine monadischen Struktur und kann mit klassischen Funktionen solcher Strukturen verwendet werden, :

flatMap [X] (f: A => JsResult [X]): JsResult [X]

etc

Aber dann gehen die Dokumentation weiter:

Bitte beachten Sie, dass JsResult [A] nicht nur Monadic aber Applicative weil sie Fehler kumulieren. Dieses kumulative Feature macht JsResult [T] macht es nicht sehr gut mit zum Verständnis verwendet werden, weil Sie nur den ersten Fehler und nicht alle erhalten.

Da, wie ich es verstehe, ein for-comprehension syntaktischer Zucker für flatMap ist, wie kann JsResult sowohl ein Applicative und Monad?

+0

Werfen Sie einen Blick auf Scalaz 'Validation' um genau zu sehen, was das bedeutet. – wheaties

+0

@wheaties, ah es ist in dem Buch (Funktionale Programmierung in Scala) Übung, an der ich gearbeitet habe - https://github.com/kman007us/side-work/blob/master/MonadsSbt/src/main/scala/ Applikativ/ValidierungApplicative.scala. Es ist das gleiche, ja? So können Sie Validierung durchführen und * alle * Fehler über 'Monad' oder' Applicative' lesen? –

+1

Ich werde diese Frage eigentlich nicht beantworten, denn ich bin mir sicher, dass ich es vermasseln würde. Fügen Sie 'Monad' und' Applicative' zu ​​Ihren Tags hinzu und ich wette, dass noch ein paar Augäpfel antworten werden. Grundsätzlich fügt ein 'Applicative' zwei weitere Methoden' pure' und '<*>' hinzu. Letzteres ist, was "löst" das Problem der Verkettung der Ausnahmen (vorausgesetzt, sie sind in einer "Semigroup" gehalten.) – wheaties

Antwort

4

Monad ist eine Unterklasse von Applicative. Applicativeapply ist schwächer als flatMap. Somit könnte in Bezug auf flatMap implementiert werden.

Aber im JsResult (oder tatsächlich Reads) Fall hat es spezielle Implementierung, die Applicative Berechnung der statische Form ausnutzt.

z. die beiden Definitionen unten verhalten sich in äquivalenter Weise mit der richtigen JSON, noch Applicative haben bessere Fehlermeldungen in fehlerhaften Fällen (die and verwendet) (zB erwähnt, wenn beide bar und quux ungültig sind):

val applicativeReads: Reads[Foo] = (
    (__ \ "bar").read[Int] and 
    (__ \ "quux").read[String] 
)(Foo.apply _) 

val monadicReads: Reads[Foo] = for { 
    bar <- (__ \ "bar").read[Int] 
    quux <- (__ \ "quux").read[String] 
} yield Foo(bar, quux)