2011-12-13 13 views
14

¿Cómo compongo dos funciones devolviendo validaciones? Los siguientes son mis intentos que no han funcionado:¿Cómo puedo usar la composición de Kleisli con funciones que devuelven validaciones?

scala> def f: Int => Validation[String, Int] = i => if(i % 2 == 0) Success(i * 2) else Failure("Odd!") 
f: Int => scalaz.Validation[String,Int] 

scala> def g: Int => Validation[String, Int] = i => if(i > 0) Success(i + 1) else Failure("Not positive!") 
g: Int => scalaz.Validation[String,Int] 

scala> kleisli(f) >=> kleisli(g) 
<console>:16: error: no type parameters for method kleisli: (f: A => M[B])scalaz.Kleisli[M,A,B] exist so that it can be applied to arguments (Int => scalaz.Validation[String,Int]) 
--- because --- 
argument expression's type is not compatible with formal parameter type; 
found : Int => scalaz.Validation[String,Int] 
required: ?A => ?M[?B] 

       kleisli(f) >=> kleisli(g) 
      ^

scala> type Va[+A] = Validation[String, A] 
defined type alias Va 

scala> kleisli[Va, Int, Int](f) >=> kleisli[Va, Int, Int](g) 
<console>:17: error: could not find implicit value for parameter b: scalaz.Bind[Va] 
       kleisli[Va, Int, Int](f) >=> kleisli[Va, Int, Int](g) 
            ^

Esto funciona en Haskell, por lo que espero no debe haber una manera de hacer esto con Scalaz también.

λ> let f i = if i `mod` 2 == 0 then Right $ i * 2 else Left "Odd!" 
λ> let g i = if i > 0 then Right $ i + 1 else Left "Not positive!" 
λ> let h = f >=> g 
λ> h 11 
Left "Odd!" 
λ> h (-4) 
Left "Not positive!" 
λ> h 4 
Right 9 

Respuesta

14

debe importar desde Validation.Monad._> => requiere un aprieto [M]

scala> import scalaz._, Scalaz._ 
import scalaz._ 
import Scalaz._ 

scala> def f: Int => Validation[String, Int] = i => if(i % 2 == 0) Success(i * 2) else Failure("Odd!") 
f: Int => scalaz.Validation[String,Int] 

scala> def g: Int => Validation[String, Int] = i => if(i > 0) Success(i + 1) else Failure("Not positive!") 
g: Int => scalaz.Validation[String,Int] 

scala> type Va[+A] = Validation[String, A] 
defined type alias Va 

scala> import Validation.Monad._ 
import Validation.Monad._ 

scala> kleisli[Va, Int, Int](f) >=> kleisli[Va, Int, Int](g) 
res0: scalaz.Kleisli[Va,Int,Int] = [email protected] 

scala> res0(11) 
res1: Va[Int] = Failure(Odd!) 

scala> res0(-4) 
res2: Va[Int] = Failure(Not positive!) 

scala> res0(4) 
res3: Va[Int] = Success(9) 
+0

que funcionó. ¡Muchas gracias! :-) – missingfaktor

Cuestiones relacionadas