Yann Moisan
Yann Moisan

Reputation: 8281

run a side effect and return errors on a ValidationNel

I need a combinator that run the side-effect on the success and return errors on a ValidationNel.

Here is my first attempt :

def runSideEffectAndReturnErrors[E, A](v: ValidationNel[E, A], f: A => Unit) : Seq[E] = v match {
  case Failure(errors) => errors.list
  case Success(a) =>
    f(a)
    Seq.empty[E]
}

And here is the second. It may have an extra cost at runtime but I find it more readable and leverage existing combinator.

def runSideEffectAndReturnErrors[E, A](v: ValidationNel[E, A], f: A => Unit) : Seq[E] = {
  v.foreach(f)
  v.fold(_.list, _ => Seq.empty[E])
}

What do you think ? Is there a better way ?

Upvotes: 1

Views: 55

Answers (1)

Travis Brown
Travis Brown

Reputation: 139058

This is largely a matter of personal taste, but I find the following a bit nicer than either of those versions:

import scalaz._, Scalaz._

def RSEaRE[E, A](v: ValidationNel[E, A], f: A => Unit): Seq[E] =
  v.map(f).fold(_.list.toList, _ => Nil)

Or:

def RSEaRE[E, A](v: ValidationNel[E, A], f: A => Unit): Seq[E] =
  v.map(f).swap.map(_.list.toList).getOrElse(Nil)

Or just:

def RSEaRE[E, A](v: ValidationNel[E, A], f: A => Unit): Seq[E] =
  v.fold(_.list.toList, a => { f(a); Nil })

Which is pretty close to your first version.

(Note that I'm using 7.2.0—it looks like you're on an earlier version, in which case you don't need toList.)

Upvotes: 1

Related Questions