2014-10-02 4 views
7

प्राप्त करने के लिए सूची [अनुक्रम [जी [ए]]] पर अनुक्रम चलाने के लिए कैसे करें F[G[List[A]]] में अच्छी तरह से बदलना संभव है?एफ [जी [सूची [ए]]]

मैं Scalaz में निम्नलिखित तरीका यह कर सकते हैं:

val x: List[Future[Option[Int]]] = ??? 
val transformed: Future[Option[List[Int]]] = x.sequenceU.map(_.sequenceU) 

मैं सिर्फ वहाँ एक अच्छा तरीका यह करने के बजाय .sequenceU.map(_.sequenceU) करने के लिए शायद एक इकाई ट्रांसफार्मर का उपयोग कर अगर सोच रहा हूँ? मैंने बहुत भाग्य के बिना इसका प्रयास किया।

उत्तर

5

यदि आप नेस्टेड अनुक्रमण से बचना चाहते हैं तो मोनाड ट्रांसफार्मर जाने का तरीका हैं। इस मामले में आप एक OptionT[Future, A] चाहते हैं (जो Future[Option[A]] के बराबर है):

import scalaz._, Scalaz._ 
import scala.concurrent.ExecutionContext.Implicits.global 
import scala.concurrent.Future 

val xs = List(OptionT(Future(some(1))), OptionT(Future(some(2)))) 
val ys = OptionT(Future(none[Int])) :: xs 

val sequencedXs: Future[Option[List[Int]]] = xs.sequenceU.run 
val sequencedYs: Future[Option[List[Int]]] = ys.sequenceU.run 

और फिर:

scala> sequencedXs.foreach(println) 
Some(List(1, 2)) 

scala> sequencedYs.foreach(println) 
None 

जैसी उम्मीद थी।

+0

जब आप इसके बारे में सोचते यह काफी स्पष्ट है, वास्तव में धन्यवाद। –

0

मैंने महसूस किया गया है एक इकाई ट्रांसफार्मर यहाँ महान है, जबकि, मैं लाभ रचना applicatives कि ले जा सकते हैं कि:

def transform[F[_], G[_], A](list: List[F[G[A]]])(implicit af: Applicative[F], ao: Applicative[G]): F[G[List[A]]] = { 
    type λ[α] = F[G[α]] 
    implicit val applicative: Applicative[λ] = af compose ao 
    list.sequence[λ, A] 
} 
val lfo: List[Future[Option[Int]]] = List(Future(1.some), Future(2.some)) 
val future: Future[Option[List[Int]]] = transform(lfo) 

और फिर:

scala> future.foreach(println) 
Some(List(1, 2)) 
+0

जो, निश्चित रूप से, लार्स ने उस समय सुझाव दिया, लेकिन यह मेरे लिए तब क्लिक नहीं किया। https://twitter.com/larsr_h/status/517997668866723840 –