1
votes

I'm working with Scalaz validations and I've run into a situation like this (note this is heavily simplified from my actual code, but the idea is the same)

Given:

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)

I would like to be able to do something along the lines this:

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

Of course if there were any errors, either in the list or outside of the list I'd like them to accumulate as they normally would.

I know the above syntax does not work, but any advice on how to achieve the result I'm looking for would be appreciated.

1
I'm not sure I understand exactly what you're asking, but you're aware that l1.sequenceU will give you a validation containing a list of x1 and x2? - Travis Brown
Ah, I didn't realize that. Just tried it and that does the trick. Thanks. - Bryan Cosgrove

1 Answers

2
votes

If you have a List[F[A]] and F has an applicative functor instance, you can turn the list inside out in effect with sequenceU to get a F[List[A]]:

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

Or:

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

It's also worth noting that if you find yourself writing things of the xs.map(f).sequenceU, you can use xs.traverseU(f) instead—it's exactly equivalent except you don't build an intermediate list.