验证是否为SemiGroup / Monoid:使用| + |不起作用

时间:2012-06-04 14:41:05

标签: scalaz

我觉得验证可以用作Monoid / SemiGroup 我在scala 2.9.2和scalaz 7 snapshot

下尝试了以下代码
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 |+| failureB给出 res1: 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

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

1 个答案:

答案 0 :(得分: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的原因。显然,如果左边的元素是ValidationSemigroup不是,Semigroup是),则Nothing会有String个实例。这是一个instance

UPD:此外,正如您所见,Semigroup实例获得了第一个Success,而不是使用Success'es Semigroup实例。我知道,Validation中有一个方法append,它要求左右元素都为Semigroup并使用两个实例:

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

不知道为什么Validation的{​​{1}}实例中没有使用它。创建了pull request来更改此行为。