Compor play.api.concurrent.Promise and scalaz.Validation usando a seta de Kleisli

Se você usar scalaz.Validation (e deveria) dentro do aplicativo Play 2.0, você pode acabar com poucas operações sequenciais assíncronas e usar para compreensão ou flatMap aninhado para obter o resultado.

Aqui está uma abordagem muito melhor (com base no Scalaz 6)

import play.api.Play.current
import play.api.libs.concurrent.{Promise,Akka}
import scalaz._
import Scalaz._

type VA
[T] = Promise[ValidationNEL[String, T]]

implicit def VABind = new Bind[VA] {
def bind[A,B](a: VA[A], f: A => VA[B]) = a.flatMap { res =>
res
.fold(e => Promise.pure(e.fail), s => f(s))
}
}

val p1
: Int => VA[Int] = a => Akka.future { if(a > 0) a.success else "negative".fail.liftFailNel }
val p2
: Int => VA[Int] = a => Akka.future { if(a % 2 === 0) a.success else "not 2x".fail.liftFailNel }
val p3
: Int => VA[Int] = a => Akka.future { if(a % 3 === 0) a.success else "not 3x".fail.liftFailNel }

val p4
: Int => VA[Int] = kleisli(p1) >=> p2 >=> p3

// uncomment to try inside play console
// new play.core.StaticApplication(new java.io.File("."))

p4
(-1).value.get // Failure(NonEmptyList(negative))
p4
(1).value.get // Failure(NonEmptyList(not 2x))
p4
(2).value.get // Failure(NonEmptyList(not 3x))
p4
(6).value.get // Failure(NonEmptyList(not 2x))