简体   繁体   English

JsResult-Monad还是适用性?

[英]JsResult - Monad or Applicative?

My understanding of one of the distinctions between Monad and Applicative is that flatMap is available on Monad , but not Applicative . 我之间的区别之一的理解MonadApplicativeflatMap可用的Monad ,而不是Applicative

If that's true, I'm confused by these Scala Play JSON docs : 如果是这样,我会对这些Scala Play JSON 文档感到困惑:

So what's interesting there is that JsResult[A] is a monadic structure and can be used with classic functions of such structures: 因此,有趣的是JsResult [A]是单子结构,并且可以与此类结构的经典功能一起使用:

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

etc 等等

But, then the docs go on to say: 但是,然后文档继续说:

Please note that JsResult[A] is not just Monadic but Applicative because it cumulates errors. 请注意,JsResult [A]不仅是Monadic的,而且是可应用的,因为它会累积错误。 This cumulative feature makes JsResult[T] makes it not very good to be used with for comprehension because you'll get only the first error and not all. 此累积功能使JsResult [T]不能很好地用于理解,因为您只会得到第一个错误,而不是全部。

Since, as I understand, a for-comprehension is syntactic sugar for flatMap , how can JsResult be both a Applicative and Monad ? 因为,据我所知,一个for-comprehension是语法糖flatMap ,怎么能JsResult既是ApplicativeMonad

Monad is a subclass of an Applicative . MonadApplicative的子类。 Applicative 's apply is weaker operation than flatMap . ApplicativeapplyflatMap操作弱。 Thus apply could be implemented in terms of flatMap . 因此apply可以用flatMap来实现。

But , in the JsResult (or actually Reads ) case, it has special implementation which exploits Applicative computation's static form. 但是 ,在JsResult (或实际为Reads )的情况下,它具有利用Applicative计算的静态形式的特殊实现。

Eg the two definitions below behave equivalently with correct JSON, yet Applicative (which uses and ) have better error messages in erroneous cases (eg mentions if both bar and quux are invalid): 例如,下面的两个定义与正确的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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM