В дополнение к ответу об отсутствующем факторе можно заметить, что у скалаза 7 нет Monad
для Validation
из-за несоответствия его поведения с экземпляром Apply
.Таким образом, можно определить Bind
для Validation
вместе с конвертерами для удобства:
import scalaz.{Bind, Kleisli, Validation, Success, Failure}
implicit def toKleisli[E, A, B](f: A => Validation[E, B]): Kleisli[Validation[E, ?], A, B] =
Kleisli[Validation[E, ?], A, B](f)
implicit def fromKleisli[E, A, B](f: Kleisli[Validation[E, ?], A, B]): A => Validation[E, B] = f.run
implicit def validationBind[E] = new Bind[Validation[E, ?]] {
def bind[A, B](fa: Validation[E, A])(f: (A) => Validation[E, B]): Validation[E, B] = {
import Validation.FlatMap._
fa.flatMap(f)
}
def map[A, B](fa: Validation[E, A])(f: (A) => B): Validation[E, B] = fa.map(f)
}
val parse: Option[String] => Validation[String, Int] = checkDefined _ >=> nonEmpty _ >=> int _
println(parse(None)) // Failure(empty)
println(parse(Some(""))) // Failure(empty)
println(parse(Some("abc"))) // Failure(java.lang.NumberFormatException: For input string: "abc")
println(parse(Some("42"))) // Success(42)