scalaz验证和列出monad

时间:2011-08-10 12:06:57

标签: validation scala scalaz

我想提出类似以下的内容:

val s: Validation[String, Int] = 1.success
def s2(i: Int): Validation[String, Int] = i.success

val result = for {
  i <- s
  j <- List(1, 2)
  k <- s2(j)
} yield "fine";

上面的代码没有编译,我理解,从语法上来说它没有意义。

我试图以monadic方式执行验证列表。我如何实现这一目标?

2 个答案:

答案 0 :(得分:8)

如果您有A的验证列表,可以使用A将其转换为sequence列表的验证:

List(1, 2).map(s2).sequence[({type l[a]=Validation[String, a]})#l, Int] 

(如果我正确理解了这个问题)。所以你得到了

val result = for {
  i <- s
  k <- List(1, 2).map(s2).sequence[({type l[a]=Validation[String, a]})#l, Int] 
} yield "fine"

答案 1 :(得分:4)

您似乎正在使用验证副作用。这不是它的精神所在。您可以在函数式编程中使用返回值。

理解中的验证继续成功,但是在失败时中断并返回失败。

scala> def g(i: Int): Validation[String, Int] = { 
          println(i); if(i % 2 == 0) i.success else "odd".fail 
       }
g: (i: Int)scalaz.Validation[String,Int]

scala> val result = for {
     |   i <- g(1)
     |   j <- g(2)
     | } yield (i,j)
1
result: scalaz.Validation[String,(Int, Int)] = Failure(odd)

scala> val result = for {
     |   i <- g(2)
     |   j <- g(1)
     | } yield (i,j)
2
1
result: scalaz.Validation[String,(Int, Int)] = Failure(odd)


scala> val result = for {
     |   i <- g(2)
     |   j <- g(2)
     | } yield (i,j)
2
2
result: scalaz.Validation[String,(Int, Int)] = Success((2,2))


scala> val result = for {
     |   i <- g(1)
     |   j <- g(1)
     | } yield (i,j)
1
result: scalaz.Validation[String,(Int, Int)] = Failure(odd)