2011-08-10 10 views
6

staram się wymyślić coś podobnego do poniższego:scalaz walidacji i lista monada

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"; 

Powyższy kod nie kompiluje i rozumiem, składniowo to nie ma sensu.

Próbuję wykonać listę walidacji w monadyczny sposób. Jak to osiągnąć?

+4

Cześć, to trochę dziwne, zobaczyć, co chcesz osiągnąć. Jeśli chcesz przeprowadzić walidację łańcuchową, proponuję zajrzeć tutaj (aplikacyjne) w linii 97, co może pomóc: https: //github.com/scalaz/scalaz/blob/master/example/src/main/scala/scalaz/example/ExampleValidation .scala – AndreasScheinert

Odpowiedz

8

Jeśli masz listę walidacji z A, można włączyć go do zatwierdzenia wykazów A wykorzystaniem sequence:

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

(jeśli dobrze rozumiem pytanie). Dostajesz więc

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

Doskonały. właśnie tego szukałem. Dzięki. – sanjib

+0

Przepraszam, odpowiedziałem za wcześnie. To prawie to, czego szukałem. Tutaj obliczane są wszystkie walidacje na liście. Miałem nadzieję, że zatrzymam obliczenia po otrzymaniu błędu. Jak mogę to zrobić ? – sanjib

+0

Nie można go przetestować w tej chwili, ale spróbuj użyć 'Stream' (to znaczy leniwej listy) zamiast' List' lub 'List (1, 2) .view.map (s2) ...'. –

4

Wydaje się, że używasz sprawdzania poprawności dla efektu ubocznego. To nie jest to, o czym jest. Wartości zwracane są używane w programowaniu funkcjonalnym.

Sprawdzanie poprawności w celu zrozumienia nadal trwa, ale powoduje awarię i zwraca błąd.

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) 
Powiązane problemy