8

我对 和 之间的区别之一的理解是on可用,但不能。MonadApplicativeflatMapMonadApplicative

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

所以有趣的是 JsResult[A] 是一个单子结构,可以与此类结构的经典函数一起使用:

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

ETC

但是,然后文档继续说:

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

既然,据我所知, afor-comprehension是 的语法糖,那么 a和flatMap怎么可能JsResult同时是?ApplicativeMonad

4

1 回答 1

4

Monad是 的子类ApplicativeApplicativeapply操作比 弱flatMap。因此apply可以根据flatMap.

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

例如,下面的两个定义与正确的 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)
于 2015-02-22T17:50:18.827 回答