Scala

2016-04-20 25 views
24

'da uygulama kılavuzları nasıl istiflenebilir? Kullanım kılavuzları genellikle hesaplama adımlarınız bağımsız olduğunda monadlere alternatif olarak belirtilir. Sık sık belirtilen avantajlarından biri, uygulamaların istiflenmesi istendiğinde transformatörlere ihtiyacınız olmamasıdır, çünkü F[G[X]] her zaman aynı zamanda bir uygulamadır. ı aşağıdaki işlevleri var diyelim:Scala

def getDataOption(): Option[Data] 
def getUserFuture(): Future[User] 
def process(data: Data, user: User) 

Ben Future[Option[User]] ve Future[Option[Data]] almak ve process o eşleştirmek için zarif istiflenmesini istiyorum.

Bugüne kadar yalnızca bu (kullanarak Kediler) ile geldi:

Applicative[Future] 
    .compose[Option] 
    .map2(
     Applicative[Future].pure(getDataOption()), 
     getUserFuture().map(Applicative[Option].pure))(process) 

ama ideal olmaktan uzak olduğuna eminim. Aynı şeyi elde etmenin daha şık ve genel bir yolu var mı?

cevap

3

En zor olanı burada sonuç çıkarsamadır. Bu da olmazsa, klişe şerit kullanışlı olacağını Eff/Emm monad benzer bir şey sanırım, ben

// for the Applicative[Future[Option[?]] 
    import cats.Applicative 

    implicit val fo = { 
    import cats.std.future._ 
    import cats.std.option._ 
    Applicative[Future].compose[Option] 
    } 

    // for the |@| syntax 
    import cats.syntax.cartesian._ 

    // to guide type inference 
    type FutureOption[A] = Future[Option[A]] 

    ((Future(getDataOption): FutureOption[Data]) |@| 
    getUserFuture.map(Option.apply)).map(process _) 
+0

Teşekkür yapabileceği en iyisidir. – kciesielski

+0

Burada yapılabilecek en kolay şey, sadece 'OptionT' almanız olabilir, ancak muhtemelen ((getDataOption) | @ | send (getUserFuture)) map (process _). RunOption.detach. Eff ile (gelecekle [Seç] [A]] Eff Eff (ve Emm ile benzer bir şey) elde edin. – Eric

+0

Sağ. Ancak, uygulamalarla kalmak istedim. Sorumluluğumun amacı, övgüye değer uygulamalı mülkün pratik bir uygulamasını görmek ve transformatör kullanmadan istiflenebilmekti. – kciesielski