I am trying to come up with something similar to the following:
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";
The above code does not compile and I understand, syntactically it does not make sense.
I am trying to execute a list of validations in a monadic way. How do I achieve that?
If you have a list of validations of A
, you can turn it into a validation of lists of A
using sequence
:
List(1, 2).map(s2).sequence[({type l[a]=Validation[String, a]})#l, Int]
(if I understand the question correctly). So you get
val result = for {
i <- s
k <- List(1, 2).map(s2).sequence[({type l[a]=Validation[String, a]})#l, Int]
} yield "fine"
You seem to be using validation for the side effect. This is not what its ment for. You use the return values in functional programming.
Validation in a for comprehension continues with on success, but breaks of at a failure and returns the failure.
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With