JsResult - Monad还是Appative?

时间:2014-01-17 15:13:50

标签: scala monads applicative playframework-json

我对MonadApplicative之间区别的一个的理解是flatMapMonad可用,但Applicative不可用for-comprehension }}

如果这是真的,我对这些Scala Play JSON docs感到困惑:

  

有趣的是,JsResult [A]是一个monadic结构   并且可以与这种结构的经典功能一起使用:

     

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

     

但是,然后文档继续说:

  

请注意,JsResult [A]不仅仅是Monadic而且是Applicative   因为它累积了错误。这个累积特征使得JsResult [T]   因为理解而使用它并不是一件好事   你只会得到第一个错误而不是全部。

据我所知,flatMapJsResult的语法糖,Applicative如何同时为Monad和{{1}}?

1 个答案:

答案 0 :(得分:4)

MonadApplicative的子类。 Applicative的{​​{3}}操作比flatMap弱。因此,apply可以flatMap实现。

,在JsResult(或实际Reads)情况下,它具有利用Applicative计算的静态形式的特殊实现。

E.g。下面的两个定义与正确的JSON等效,但Applicative(使用and)在错误的情况下有更好的错误消息(例如,如果barquux都无效,则会提及):

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)