Question

I am little confused about |@| magic in scalaz. Here is my code:

def isThree(x: Int): Validation[NonEmptyList[String], Int] = if (x!= 3){("failed: %d" format x).wrapNel.failure} else {x.success}

println((isThree(6) |@| isThree(7) |@| isThree(13) ) {_ + _ + _})

output: Failure(NonEmptyList(failed: 6, failed: 7, failed: 13)) This is output is what I want.

Here is my questions:

  1. assume I have sequence of Validation, I want to use applicative builder to chain them together.

    Seq(isThree(13), isThree(15)).reduceLeft(_ |@| _) why compilation failed due to type not matching ?

  2. It is similar to first question, if I use bracket :

    println((isThree(6) |@| (sThree(7) |@| isThree(13)) ) {_ + _ + _}), it still has compilation errors.

Also, I know I can fix the first one by using <* instead of |@|, but I am still confused why is that, it looks not convenient to use.

Many thanks in advance.

Was it helpful?

Solution

This works: |@| result type is not ValidationNel (Applicative) but ApplicativeBuilder, you need yo apply it first to some function

  import scalaz._, Scalaz._

  val x1: ValidationNel[String, Int] = 1.successNel
  val x2: ValidationNel[String, Int] = 2.successNel
  val x3: ValidationNel[String, Int] = 3.successNel

  println((x1 |@| x2 |@| x3)(_ + _ + _))

  println((x1 :: x2 :: x3 :: Nil).reduceLeft((l, r) => (l |@| r)(_ + _)))
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top