Scalaz 使用带有验证和验证列表的应用程序生成器

Scalaz use applicative builder with validations and a list of validations

我正在使用 Scalaz 验证,我 运行 遇到过这样的情况(请注意,这与我的实际代码相比已大大简化,但想法是相同的)

鉴于:

case class Foo(bar: Int)

val x1: Validation[String, Foo] = Foo(1).success
val x2: Validation[String, Foo] = Foo(2).success
val x3: Validation[String, Foo] = Foo(3).success

val l1 = List(x1, x2)

我希望能够按照以下方式做一些事情:

(x3 |@| l1) { (x1, x2, x3) => /*do something with all of my Foo's*/ } 

当然,如果有任何错误,无论是在列表中还是在列表之外,我都希望它们像往常一样累积起来。

我知道上面的语法不起作用,但是任何关于如何实现我正在寻找的结果的建议都将不胜感激。

如果你有一个 List[F[A]] 并且 F 有一个应用仿函数实例,你可以使用 sequenceU 将列表翻转过来以获得 F[List[A]]

scala> l1.sequenceU
res0: scalaz.Validation[String,List[Foo]] = Success(List(Foo(1), Foo(2)))

或者:

scala> (x3 |@| l1.sequenceU) {
  case (third, rest) => // do something with the values
}

同样值得注意的是,如果您发现自己在写 xs.map(f).sequenceU 的东西,您可以使用 xs.traverseU(f) 代替——它完全等同,只是您不构建中间列表。