diff --git a/core/src/main/scala/cats/data/Validated.scala b/core/src/main/scala/cats/data/Validated.scala index d55915dab5c..e933ce16d18 100644 --- a/core/src/main/scala/cats/data/Validated.scala +++ b/core/src/main/scala/cats/data/Validated.scala @@ -44,6 +44,7 @@ sealed abstract class Validated[+E, +A] extends Product with Serializable { /** * Return this if it is Valid, or else fall back to the given default. + * The functionality is similar to that of [[or]] except for failure accumulation. */ def orElse[EE, AA >: A](default: => Validated[EE, AA]): Validated[EE, AA] = this match { @@ -218,6 +219,18 @@ sealed abstract class Validated[+E, +A] extends Product with Serializable { */ def ensure[EE >: E](onFailure: => EE)(f: A => Boolean): Validated[EE, A] = fold(_ => this, a => if (f(a)) this else Validated.invalid(onFailure)) + + /** + * If `this` is valid return `this`, otherwise if `that` is valid return `that`, otherwise combine the failures. + * This is similar to [[orElse]] except that here failures are accumulated. + */ + def or[EE >: E, AA >: A](that: => Validated[EE, AA])(implicit EE: Semigroup[EE]): Validated[EE, AA] = this match { + case v @ Valid(_) => v + case Invalid(e) => that match { + case v @ Valid(_) => v + case Invalid(ee) => Invalid(EE.combine(e, ee)) + } + } } object Validated extends ValidatedInstances with ValidatedFunctions{