2012-11-19 11 views
9

Birisi gerçek dünya örnekleriyle açıklayabilir mi? scalaz.Validation yöntemlerinin altında çalışma nasıl çalışır? loopSuccess ve loopFailure'u kastediyorum. Kaynak kodu (scalaz7) deniş nasıl olur scalaz.Validation loopSuccess ve loopFailure

Snippetes:

scalaz.Validation:

/** Spin in tail-position on the success value of this validation. */ 
def loopSuccess[EE >: E, AA >: A, X](success: AA => X \/ Validation[EE, AA], failure: EE => X): X = 
Validation.loopSuccess(this, success, failure) 

/** Spin in tail-position on the failure value of this validation. */ 
def loopFailure[EE >: E, AA >: A, X](success: AA => X, failure: EE => X \/ Validation[EE, AA]): X = 
Validation.loopFailure(this, success, failure) 

Tamamlayıcı nesnesi:

object Validation extends ValidationFunctions with ValidationInstances { 

    /** Spin in tail-position on the success value of the given validation. */ 
    @annotation.tailrec 
    final def loopSuccess[E, A, X](d: Validation[E, A], success: A => X \/ Validation[E, A], failure: E => X): X = 
    d match { 
     case Failure(e) => failure(e) 
     case Success(a) => success(a) match { 
     case -\/(x) => x 
     case \/-(q) => loopSuccess(q, success, failure) 
     } 
    } 

    /** Spin in tail-position on the failure value of the given validation. */ 
    @annotation.tailrec 
    final def loopFailure[E, A, X](d: Validation[E, A], success: A => X, failure: E => X \/ Validation[E, A]): X = 
    d match { 
     case Failure(e) => failure(e) match { 
     case -\/(x) => x 
     case \/-(q) => loopFailure(q, success, failure) 
     } 
     case Success(a) => success(a) 
    } 

} 

cevap

5

Bu trampoline benzerdir. loopSuccess için, bir başlangıç ​​değeri ve sizi bir sonraki duruma götüren bir işlev sağlarsınız. loopFailure için

X.left   // stop processing with X as the result 
Success(a).right // no result, run the next iteration with this value 
Failure(e).right // stop processing, run the failure function on this result and return it 

Yetmezliğe aynı şeyi yapar ve Sol veya bir Başarı dönünceye kadar yayınlanmaya devam etmesi Başarı, geri alındı: 3 olası sonraki durumu vardır.

import scalaz._ 
import Scalaz._ 

object TestLoopSuccess extends App { 
    // check if a number divides another, returning a Failure for division by zero 
    val divides : Int => Int => Validation[String,Boolean] = { div => num => 
    if(div == 0) "division by zero".failure 
    else (num % div == 0).success 
    } 

    val allDivide : Int => List[Int] => String \/ Validation[Int,List[Int]] = { div => nums => 
    nums match { 
     // empty list means we are done, so we return a left 
     case Nil => "All numbers divide".left 

     // process the head of the list and return a right 
     case x::xs => divides(div)(x).flatMap { divides => 
     if(divides) 
      // head divides, so process more of the list 
      xs.success 
     else 
      // head does not divide, so we are done 
      "%d is not a multiple of %d".format(x,div).failure 
     }.right 
    } 
    } 

    println(Validation.loopSuccess(List(2,4,6,8).success[String], allDivide(0), identity[String])) // "division by zero" 
    println(Validation.loopSuccess(List(2,4,6,8).success[String], allDivide(2), identity[String])) // "All numbers divide" 
    println(Validation.loopSuccess(List(2,4,7,8).success[String], allDivide(2), identity[String])) // "7 is not a multiple of 2" 
} 
: Burada

kullanılarak loopSuccess bir örneğidir
İlgili konular