2013-02-18 20 views
5

I fonksiyonel programlama çalışmalarında bir acemi ve ben ValidationNEL [A, B] dizisi var ve ben yeni bir ValidationNEL içine hataları birikir istiyoruz [A, B]. Bu B eski kod gelen değişken veri yapısı olduğunu ve yüzden bir Seq [B] tutmak için oververbose olacağını gerçeğine bağlıdır. Processing a list of Scalaz6 ValidationBiriken sadece doğrulama hataları Scalaz

Benim anlayış hepsi uygun bir uygulamalı ve belki uygun bir çapraz geçiş yazma gelince:

I hatalarından ve başarıyı cumulating dizisi yöntemiyle mümkün olduğunu diğer yayınlardan biliyoruz.

trait MA[M[_], A] extends PimpedType[M[A]] with MASugar[M, A] { 

    def sequence[N[_], B](implicit a: A <:< N[B], t: Traverse[M], n: Applicative[N]): N[M[B]] = 
    traverse((z: A) => (z: N[B])) 

    def traverse[F[_],B](f: A => F[B])(implicit a: Applicative[F], t: Traverse[M]): F[M[B]] = 
    t.traverse(f, value) 
    } 

Nasıl başlarım? Benim uygulamalı nasıl uygulanacağını öğrenmek için Scalaz kaynak koduna aramaya çıktığında, ben son derece karıştı. Hangi başvurunun, hem başarısızlıkların hem de Validasyondaki başarının birikmesine izin vereceğini bile öğrenemedim. Şimdi biraz daha iyi sorunuzu anlaması

+0

Eğer Seq dan [ValidtionNEL [A, B]] ValidationNEL [A, Sek [B]] ya da bir şey benzer gitmeye çalışıyorsunuz? – Noah

+0

Hayır Seq [ValidtionNEL [A, B]] - ValidationNEL [A, B] – Edmondo1984

+0

Bu nedenle ValidationNEL yalnızca Doğrulama [NonEmptyList [A], B] olur, böylece B'yi birlikte ekleyemezseniz sorduğunuz şeyi yapamazsınız (ints , listeler, vb. – Noah

cevap

3

ama Scalaz 7.0.4 itibariyle, bunu yapabilirsiniz:

def takeLastSuccess[A, B](seq: Seq[ValidationNel[A, B]]) = { 
     implicit val useLast = Semigroup.lastSemigroup[B] 
     seq reduceLeft (_ +++ _) 
    } 
2

, bu oldukça yalındır:

def takeLastSuccess[A, B](seq:Seq[ValidationNEL[A, B]]) = 
    seq.sequence[({type l[a] = ValidationNEL[A, a]})#l, B].map(_.last) 

Eğer bir tip lambda kullanmak gerekir bu yüzden bu Scala türleri ile bazı sorunlar vardır diziye zaman. Sıra Sek gitmek için güzel bir kısa yoldur [şey [X]] Something [Seri [X]]. Son olarak, sadece başarının haritasını çıkarırız ve son B'yi B dizisinden alırız. the post you cited örneğin çektin

, burada repl aldığım budur: partiye Geç

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

scala> type ExceptionsOr[A] = ValidationNEL[Exception, A] 
defined type alias ExceptionsOr 

scala> val successResults: Seq[ExceptionsOr[Int]] = Seq(
    |  "13".parseInt.liftFailNel, "42".parseInt.liftFailNel 
    | ) 
successResults: Seq[ExceptionsOr[Int]] = List(Success(13), Success(42)) 

scala> val failResults: Seq[ExceptionsOr[Int]] = Seq(
    |  "13".parseInt.liftFailNel, "a".parseInt.liftFailNel, "b".parseInt.liftFailNel 
    | ) 
failResults: Seq[ExceptionsOr[Int]] = List(Success(13), Failure(NonEmptyList(java.lang.NumberFormatException: For input string: "a")), Failure(NonEmptyList(java.lang.NumberFormatException: For input string: "b"))) 

scala> def takeLastSuccess[A, B](seq:Seq[ValidationNEL[A, B]]) = seq.sequence[({type l[a] = ValidationNEL[A, a]})#l, B].map(_.last) 
takeLastSuccess: [A, B](seq: Seq[scalaz.Scalaz.ValidationNEL[A,B]])scalaz.Validation[scalaz.NonEmptyList[A],B] 

scala> takeLastSuccess(successResults) 
res0: scalaz.Validation[scalaz.NonEmptyList[Exception],Int] = Success(42) 

scala> takeLastSuccess(failResults) 
res1: scalaz.Validation[scalaz.NonEmptyList[Exception],Int] = Failure(NonEmptyList(java.lang.NumberFormatException: For input string: "a", java.lang.NumberFormatException: For input string: "b")) 
+0

Bu zaten uygulamış ne benzer bir çözümdür. İdeal çözüm, arzu ettiğim gibi çalışabilmek için dizi metodu için doğru bir Uygulamanın sağlanmasıdır. – Edmondo1984

İlgili konular