使用reduceLeft的应用程序构建器的scalaz

时间:2014-04-25 02:34:37

标签: validation scala scalaz applicative

我对| @ |感到困惑斯卡拉兹的魔法。这是我的代码:

def isThree(x: Int): Validation[NonEmptyList[String], Int] = if (x!= 3){("failed: %d" format x).wrapNel.failure} else {x.success}

println((isThree(6) |@| isThree(7) |@| isThree(13) ) {_ + _ + _})

输出:失败(NonEmptyList(失败:6,失败:7,失败:13)) 输出就是我想要的。

以下是我的问题:

  1. 假设我有验证序列,我想使用applicative builder将它们链接在一起。

    Seq(isThree(13),isThree(15))。reduceLeft(_ | @ | _) 为什么编译因类型不匹配而失败?

  2. 如果我使用括号

    ,则与第一个问题类似

    println((isThree(6) |@| (sThree(7) |@| isThree(13)) ) {_ + _ + _}),它仍然存在编译错误。

  3. 另外,我知道我可以使用< *而不是| @ |来修复第一个,但我仍然感到困惑,为什么这样,使用起来不方便。

    非常感谢提前。

1 个答案:

答案 0 :(得分:2)

这适用于:| @ |结果类型不是ValidationNel(Applicative)但是ApplicativeBuilder,你需要先将它应用到某个函数

  import scalaz._, Scalaz._

  val x1: ValidationNel[String, Int] = 1.successNel
  val x2: ValidationNel[String, Int] = 2.successNel
  val x3: ValidationNel[String, Int] = 3.successNel

  println((x1 |@| x2 |@| x3)(_ + _ + _))

  println((x1 :: x2 :: x3 :: Nil).reduceLeft((l, r) => (l |@| r)(_ + _)))