Cálculo asíncrono con validación en Scala usando Scalaz

Al estar escribiendo una biblioteca completamente asíncrona para acceder a un servicio remoto (usando Play2.0), estoy usandoPromise yValidation para crear una llamada no bloqueante, que tiene un tipo que presenta un error y un resultado válido a la vez.

Promise viene de play2-scala, dondeValidation viene de scalaz.

Así que aquí está el tipo de ejemplos de tales funciones.

f ::A => Promise[Validation[E, B]]g ::B => Promise[Validation[E, C]]

Hasta ahora, todo bien, ahora, si quiero componerlos, puedo usar simplemente el hecho de quePromise presentar unflatMap, asi lo puedo hacer con una comprension

for (
   x <- f(a);
   y <- g(b)
) yield y

Ok, tomé un atajo a mi problema aquí porque no reutilizé elValidation Resultados dentro de la para-comprensión. Así que si quiero reutilizar.x eng, aquí es como podría hacer

for (
   x <- f(a); // x is a Validation
   y <- x.fold(
      fail => Promise.pure(x),
      ok => g(ok)
   )
) yield y

Justo lo suficiente, pero este tipo de repetición irá a contaminar mi código una y otra vez. El problema aquí es que tengo una especie de estructura monádica de dos niveles comoM[N[_]].

En esta etapa, ¿hay alguna estructura en la programación en grados que permita trabajar con dicha estructura saltando fácilmente el segundo nivel:

for (
   x <- f(a); //x is a B
   y <- g(b) 
) yield y

Ahora, a continuación es cómo logré algo similar.

Creé una especie de estructura monádica que envuelve los dos niveles en uno, digamosValidationPromised el cual engullía elPromise tipo con dos métodos:

def /~> [EE >: E, B](f: Validation[E, A] => ValidationPromised[EE, B]): ValidationPromised[EE, B] = 
    promised flatMap { valid => 
        f(valid).promised
    }

def /~~>[EE >: E, B](f: A => ValidationPromised[EE, B]): ValidationPromised[EE, B] = 
    promised flatMap { valid => 
        valid.fold (
            bad => Promise.pure(KO(bad)),
            good => f(good).promised
        )
    }

Esto me permite hacer esas cosas.

      endPoint.service /~~>                                   //get the service
      (svc =>                                                 //the service
        svc.start /~~> (st =>                                 //get the starting elt
          svc.create(None) /~~>                               //svc creates a new elt
          (newE =>                                            //the created one
            newEntry.link(st, newE) /~~>                      //link start and the new
            (lnk => Promise.pure(OK((st, lnk, newE))))        //returns a triple => hackish 
          ) 
        )
      )

Como podemos ver/~~> es bastante similar aflatMap pero se salta un nivel. El problema es la verbosidad (es por eso que "para-comprensión" existe en Scala y "hacer" en Haskell).

Otro punto, tengo el/~> eso es como unmap también, pero funciona en el segundo nivel (en lugar del tipo Válido -tercero nivel)

Entonces, mi segunda pregunta es corolario de la anterior ... ¿Estoy buscando una solución sostenible con esta construcción?

Lamento ser tan largo

Respuestas a la pregunta(1)

Su respuesta a la pregunta