Scalaz adaptive linker syntax ( |@| ) gives you a way to βliftβ functions into an applicative functor. Suppose we have the following results, for example:
val xs: ValidationNel[String, List[Int]] = "Error!".failNel val ys: ValidationNel[String, List[Int]] = List(1, 2, 3).success val zs: ValidationNel[String, List[Int]] = List(4, 5).success
We can raise the list concatenation function ( ++ ) in Validation as follows:
scala> println((ys |@| zs)(_ ++ _)) Success(List(1, 2, 3, 4, 5)) scala> println((xs |@| ys)(_ ++ _)) Failure(NonEmptyList(Error!)) scala> println((xs |@| xs)(_ ++ _)) Failure(NonEmptyList(Error!, Error!))
This syntax is a little strange - it is very different from how you, for example, raise functions into an applicative functor in Haskell, and is designed in such a way as to outwit a system of insanity like w60. See my answer here or blog post here for further discussion.
One part of the oddity is that xs |@| ys xs |@| ys doesn't really mean anything - it's essentially a list of arguments to be applied to a function that it will raise to its application functor and apply to itself.
+++ on Validation is a much simpler creature view - it's just the operation of adding a Semigroup instance to a type (note that you can equivalently use the semigroup operator Scalaz |+| here instead of +++ ). You give it two Validation results with the corresponding semigroup types, and it gives you another Validation not some terrible ApplyOps thing.
As an additional note, in this case the addition operation for the Validation semigroup coincides with the operation of the right-hand semigroup raised in Validation :
scala> (xs |+| ys) == (xs |@| ys)(_ |+| _) res3: Boolean = true
This will not always be the case, however (this is not for \/ , for example, when a semigroup accumulates errors, but the applicative functor does not).