2016-01-11 66 views
4

考慮到以下3個功能,如何應對閱讀器[A,未來的[B]

def f[A, B] : Reader[A, B] = ??? 
def g[A, B, C](b: B) : Reader[A, Future[C]] = ??? 
def h[A, C, D](c: C) : Reader[A, D] = ??? 

如何寫一元組合子?

這是我目前的解決辦法,但我不是真正的快樂與所有這些boilerplates

def f2[A, B] : ReaderT[Future, A, B] = kleisli { 
    a => Future.successful(f.run(a)) 
} 

def h2[A, C, D](c: C) : ReaderT[Future, A, D] = kleisli { 
    a => Future.successful(h(c).run(a)) 
} 

def g2[A, B, C](b: B) : ReaderT[Future, A, C] = kleisli { 
    a => g(b).run(a) 
} 

def i[A,B,C,D] : ReaderT[Future, A, (B,C,D)] = 
    for { 
    b <- f2[A, B] 
    c <- g2[A, B, C](b) 
    d <- h2[A, C, D](c) 
    } yield (b,c,d) 

回答

2
def i[A,B,C,D] : ReaderT[Future, A, (B,C,D)] = 
    for { 
    b <- f[A, B].lift[Future] 
    c <- g[A, B, C](b).mapK[Future, C](identity) 
    d <- h[A, C, D](c).lift[Future] 
    } yield (b,c,d) 

我不知道是否有更好的方式來代替mapK[Future, C](identity)

+1

問題在於'g'的類型,如果你可以把它改成'ReaderT [Future,A,C]'(這是有道理的),那麼'g [A,B,C](b)會直接工作。或者,你可以寫'Kleisli [Future,A,C](g(b).run)''但我不確定它會更好。 – blouerat

相關問題