2012-06-10 19 views
7

Uzak bir hizmete erişmek için (tamamen Playync kullanarak) tamamen eşzamansız bir kütüphane yazmak (Play2.0'ı kullanarak), Promise ve Validation kullanıyorum engelleyici olmayan çağrı oluşturmak için bir tür sunma başarısız ve Bir kerede geçerli sonuç. Validation scalaz'dan geldiği Play2-scala'dan gelir.Scala'da Scala'da Doğrulama ile Async hesaplama

, Promise. Yani burada

böyle fonksiyonların

örnekleri türüdür
  • f :: A => Promise[Validation[E, B]]
  • gr :: B => Promise[Validation[E, C]]

Şu ana kadar çok iyi, şimdi onları oluşturmak istiyorsanız PromiseflatMap'u kullanıma sunabildiğim gerçeğini basit bir şekilde kullanabilirim, böylece bunu bir anlaşılabilirlikle yapabilirim

Sorunumun bir kısayolunu aldım çünkü anlama-anlama için Validation sonuçlarını tekrar kullanmadım. Ben g yılında x yeniden kullanmak istiyorsanız, buraya yeterince

for (
    x <- f(a); // x is a Validation 
    y <- x.fold(
     fail => Promise.pure(x), 
     ok => g(ok) 
    ) 
) yield y 

Adil yapabileceğini nasıl olduğunu, ancak Demirbaş bu tür tekrar tekrar kodumu kirletmeye gidecek Yani. Buradaki problem, M[N[_]] gibi bir iki seviyeli Monadic yapı olduğum.

for (
    x <- f(a); //x is a B 
    y <- g(b) 
) yield y 

aşağıda, Şimdi benzer bir şey elde nasıl: Bu aşamada

, kolayca secong seviyesini atlayarak böyle yapısıyla çalışma imkanı programlama ° f herhangi bir yapı yoktur.

ben, birinde iki seviyesini sarar Monadik tür yapısını oluşturdu iki yöntem ile Promise tip pimped ValidationPromised diyelim: Bu bana böyle şeyler

 endPoint.service /~~>         //get the service 
     (svc =>             //the service 
     svc.start /~~> (st =>         //get the starting elt 
      svc.create(None) /~~>        //svc creates a new elt 
      (newE =>           //the created one 
      newEntry.link(st, newE) /~~>      //link start and the new 
      (lnk => Promise.pure(OK((st, lnk, newE))))  //returns a triple => hackish 
     ) 
     ) 
    ) 
yapmanızı sağlar

def /~> [EE >: E, B](f: Validation[E, A] => ValidationPromised[EE, B]): ValidationPromised[EE, B] = 
    promised flatMap { valid => 
     f(valid).promised 
    } 

def /~~>[EE >: E, B](f: A => ValidationPromised[EE, B]): ValidationPromised[EE, B] = 
    promised flatMap { valid => 
     valid.fold (
      bad => Promise.pure(KO(bad)), 
      good => f(good).promised 
     ) 
    } 

/~~>'u görebildiğimiz gibi flatMap'a oldukça benziyor ancak bir seviye atlıyor. Sorun, ayrıntıdır (Scala'da "anlama-anlama" ve Haskell'de "do").

başka nokta, ben de bir map gibi duruyor ama ikinci düzeyde çalışır /~> ettik (yerine geçerlidir Çeşidi - üçüncü seviyesi)

Yani ikinci sorum birincisine sonucudur ... Bu inşaat ile sürdürülebilir bir çözümü onaylıyorum? Özür

uzun

+0

şimdi bir süre kendi Çal uygulamalarıyla ScalaZ kullanmak istiyordum ve bu benim için iyi bir dürtüşüdür. Nasıl geçeceğimi size bildiririm ve umarım buradaki anlamlı bir cevabı koyabilirler. – opyate

+0

Evet! Teşekkürler. Aslında asıl sorun Play ile ScalaZ kullanmıyor. Bu daha genel bir soru (f ° prog hakkında), çünkü Play olmadan (sadece ScalaZ) 'Promise' yerine' IO 'kullandım. Bu yüzden, ben de aynı kalıba sahip olurdum, demek istediğim: 'IO [Validasyon [E, A]]' –

cevap

4

Burada aradığınız kavram monad transformers olduğunu olmak. Kısaca, monad transformatörleri, onları "istiflemenize" olanak sağlayarak monads not composing'u telafi eder.

Kullandığınız Scalaz sürümünden bahsetmediniz, ancak scalaz-seven branch'a bakarsanız, ValidationT'u bulacaksınız. Bu, herhangi bir F[Validation[E, A]]'u ValidationT[F, E, A] içine sarmak için kullanılabilir, burada sizin durumunuzda F = Promise. Eğer ValidationT dönmek f ve g değiştirirseniz, o zaman bu bir sonucu olarak size ValidationT[Promise, E, B] verecek

for { 
    x ← f(a) 
    y ← g(b) 
} yield y 

olarak kodunuzu bırakabilirsiniz.

+0

MMmh, aradığım şey gibi görünüyor! Tamam, ben ilk önce monad transformatör ile kendi kendime çalışacağım, iki sebepten dolayı, çünkü öğrenmenin tek yolu, ve ikincisi 6.0.4 dalında olduğum için. Ve sonra muhtemelen 7'ye gideceğim ve ValidatorT için yeniden kayıt yapacağım. Her durumda, daha fazlasını söylemek için buraya geri geleceğim. Tekrar teşekkürler –

+0

Tamam. Harika doktor. 'ValidasyonT'üne baktım,' flatMap' yöntemi gerçekten ihtiyacım olan şey (ve tahmin etmek istediğim gibi benim// ~~> ile aynıdır). Fakat bunu doğrudan kullanabilmek için, 'Promise',' Monad'ın bir TypeClass örneğine gereksinim duyar, ki bu da değil. ScalaZ çıkınca, ValidationT'yi doğrudan kullanabilmek için onu uygulayacağım. –