5

In Nick Partridge's presentation on deriving scalaz, based on an older version of scalaz, he introduces validations using a function:

def even(x: Int): Validation[NonEmptyList[String], Int] =
  if (x % 2 == 0) x.success else { s"not even: $x".wrapNel.failure }

Then he combines this using

even(1) <|*|> even(2)

which applies the test and returns a validation with the failure message. Using scalaz 7 I get

scala> even(1) <|*|> even(2)
<console>:18: error: value <|*|> is not a member of scalaz.Validation[scalaz.NonEmptyList[String],Int]
       even(1) <|*|> even(2)
               ^

What is the scalaz 7 equivalent of this combinator?

Joe Kearney
  • 7,397
  • 6
  • 34
  • 45
  • Wouldn't you rather want to use `|@|` operator ? The video you posted does not mention it but you can find out more about it here: http://eed3si9n.com/learning-scalaz/Validation.html – mjaskowski Oct 07 '15 at 21:13
  • In particular you can then write `scala> (even(1) |@| even(2) |@| even(3)) { _ + _ + _}` `Failure(NonEmptyList(not even: 1, not even: 3))` and `scala> (even(2) |@| even(4) |@| even(6)) { _ + _ + _})` ` Success(12)` – mjaskowski Oct 07 '15 at 21:23
  • @mjaskowski `|@|` is very generic, and in cases where you just want to zip together two values in a tuple, `tuple` (previously known as `<|*|>`) is more appropriate. – Travis Brown Oct 08 '15 at 02:47

2 Answers2

5

This is now called tuple, so you can write for example:

import scalaz._, Scalaz._

def even(x: Int): Validation[NonEmptyList[String], Int] =
  if (x % 2 == 0) x.success else s"not even: $x".failureNel

val pair: ValidationNel[String, (Int, Int)] = even(1) tuple even(2)

Unfortunately I'm not sure there's a better way to find out this kind of thing than checking out the last 6.0 tag of the source, searching, and then comparing signatures.

Travis Brown
  • 138,631
  • 12
  • 375
  • 680
-1

You want to use the |@| operator.

scala> (even(1) |@| even(2) |@| even(3)) { (_,_,_) }
<console> Failure(NonEmptyList(not even: 1, not even: 3))

scala> (even(2) |@| even(4) |@| even(6)) { (_,_,_) }
<console> Success((2,4,6))

compare that to tuple operator:

scala> even(1) tuple even(2) tuple even(3)
<console> Failure(NonEmptyList(not even: 1, not even: 3))

scala> even(2) tuple even(4) tuple even(6)
<console> Success(((2,4),6))
mjaskowski
  • 1,479
  • 1
  • 12
  • 16
  • 2
    You definitely _can_ use `|@|` here, but I don't see any indication that that's what the OP _wants_. `|@|` existed in Scalaz 6 and did the same thing as it does in 7—`<|*|>` is something more specific that had its named changed. – Travis Brown Oct 08 '15 at 02:46
  • What good is `tuple` over `|@|` in the scenario of Validation? – mjaskowski Oct 08 '15 at 12:01
  • Why does the scenario matter? When you want a tuple, `tuple` is more precise, less powerful, more readable, and more clear about intent than `|@|`—these are all reasons to prefer it. – Travis Brown Oct 08 '15 at 12:48
  • Well anyway, for someone learning about Validation, knowledge about `|@|` is at least as important as knowledge about `tuple`. And in the particular example in question both are fine. – mjaskowski Oct 08 '15 at 14:24