2011-08-10 4 views
6

J'essaie de trouver quelque chose de semblable à ce qui suit:validation scalaz et la liste monade

val s: Validation[String, Int] = 1.success 
def s2(i: Int): Validation[String, Int] = i.success 

val result = for { 
    i <- s 
    j <- List(1, 2) 
    k <- s2(j) 
} yield "fine"; 

Le code ci-dessus ne compile pas et je comprends, syntaxiquement il n'a pas de sens. J'essaye d'exécuter une liste de validations d'une manière monadique. Comment puis-je y parvenir?

+4

Salut, c'est un peu étrange de voir ce que vous voulez réaliser. Si vous voulez enchaîner les validations, je suggère de regarder ici (applicatif) à la ligne 97 peut-être cela aide: https: //github.com/scalaz/scalaz/blob/master/example/src/main/scala/scalaz/example/ExampleValidation .scala – AndreasScheinert

Répondre

8

Si vous avez une liste de validations de A, vous pouvez le transformer en une validation des listes de A utilisant sequence:

List(1, 2).map(s2).sequence[({type l[a]=Validation[String, a]})#l, Int] 

(si je comprends bien la question). Vous obtenez donc

val result = for { 
    i <- s 
    k <- List(1, 2).map(s2).sequence[({type l[a]=Validation[String, a]})#l, Int] 
} yield "fine" 
+0

Excellent. c'est exactement ce que je cherchais. Merci. – sanjib

+0

Désolé, répondu trop tôt. C'est presque ce que je cherchais. Ici, toutes les validations dans la liste sont calculées. J'espérais arrêter le calcul une fois que je recevrais l'échec. Comment je fais ça ? – sanjib

+0

Impossible de le tester pour le moment, mais essayez d'utiliser 'Stream' (c'est-à-dire liste paresseuse) au lieu de' List', ou 'List (1, 2) .view.map (s2) ...'. –

4

Vous semblez utiliser la validation pour l'effet secondaire. Ce n'est pas ce à quoi cela sert. Vous utilisez les valeurs de retour dans la programmation fonctionnelle.

La validation dans un pour la compréhension se poursuit en cas de succès, mais casse à un échec et renvoie l'échec.

scala> def g(i: Int): Validation[String, Int] = { 
      println(i); if(i % 2 == 0) i.success else "odd".fail 
     } 
g: (i: Int)scalaz.Validation[String,Int] 

scala> val result = for { 
    | i <- g(1) 
    | j <- g(2) 
    | } yield (i,j) 
1 
result: scalaz.Validation[String,(Int, Int)] = Failure(odd) 

scala> val result = for { 
    | i <- g(2) 
    | j <- g(1) 
    | } yield (i,j) 
2 
1 
result: scalaz.Validation[String,(Int, Int)] = Failure(odd) 


scala> val result = for { 
    | i <- g(2) 
    | j <- g(2) 
    | } yield (i,j) 
2 
2 
result: scalaz.Validation[String,(Int, Int)] = Success((2,2)) 


scala> val result = for { 
    | i <- g(1) 
    | j <- g(1) 
    | } yield (i,j) 
1 
result: scalaz.Validation[String,(Int, Int)] = Failure(odd)