3

我的印象是 Validation 可以用作 Monoid/SemiGroup 我在 scala 2.9.2 和 scalaz 7 快照下尝试了以下代码

import scalaz._
import Scalaz._

val success1 = 1.success
val success2 = 2.success

val failureA = "A".fail
val failureB = "B".fail

success1 |+| success2
<console>:16: error: diverging implicit expansion for type scalaz.Semigroup[scalaz.Validation[Nothing,Int]]
starting with method validationSemigroup in trait ValidationInstances
              success1 |+| success2
              ^
<console>:16: error: value |+| is not a member of scalaz.Validation[Nothing,Int]

              success1 |+| success2

我期待一个Success(3)

然后

failureA |+| failureBres1: scalaz.Validation[java.lang.String,Nothing] = Failure(AB) 按预期给出

success1 |+| failureA按预期失败

<console>:16: error: diverging implicit expansion for type scalaz.Semigroup[scalaz.Validation[Nothing,Int]]
starting with method validationSemigroup in trait ValidationInstances
              success1 |+| failureA
              ^
<console>:16: error: value |+| is not a member of scalaz.Validation[Nothing,Int]

              success1 |+| failureA

为什么|+|onSuccess不起作用?这是一个错误还是我在这里错过了什么

4

1 回答 1

3

它是这样工作的:

scala> import scalaz._, Scalaz._
import scalaz._
import Scalaz._

scala> val success1 = 1.success[String]
success1: scalaz.Validation[String,Int] = Success(1)

scala> val success2 = 2.success[String]
success2: scalaz.Validation[String,Int] = Success(2)

scala> val failureA = "A".fail[Int]
failureA: scalaz.Validation[java.lang.String,Int] = Failure(A)

scala> val failureB = "B".fail[Int]
failureB: scalaz.Validation[java.lang.String,Int] = Failure(B)

scala> success1 |+| success2
res0: scalaz.Validation[String,Int] = Success(1)

scala> failureA |+| failureB
res1: scalaz.Validation[java.lang.String,Int] = Failure(AB)

scala> success1 |+| failureA
res2: scalaz.Validation[String,Int] = Success(1)

您没有Failure在前两个中指定左元素 ( )的类型val。这就是Nothing推断的原因。显然,如果左元素是一个(不是,是) ,则Validation有一个实例。这是一个例子SemigroupSemigroupNothingString

UPD:另外,如您所见,Semigroup实例获得第一个Success而不是使用Success'esSemigroup实例。我看到了,有一个方法appendin Validation,它要求左右元素都是Semigroups 并使用两个实例:

scala> success1 append success2
res6: scalaz.Validation[String,Int] = Success(3)

不知道,为什么在Validation'sSemigroup实例中不使用它。创建了一个拉取请求来更改此行为。

于 2012-07-07T20:50:41.013 回答