我有四種類型A
,B
,C
和D
,類型Future[Option[A]]
和三個函數的初始值x
:f1: A => Option[B]
,f2: B => Future[Option[C]]
和f3: C => D
。創作期貨及期權
我該如何編寫for
理解,從x
開始,導致Future[Option[D]]
這個類型的值將是這三個函數的「組合」?
我有四種類型A
,B
,C
和D
,類型Future[Option[A]]
和三個函數的初始值x
:f1: A => Option[B]
,f2: B => Future[Option[C]]
和f3: C => D
。創作期貨及期權
我該如何編寫for
理解,從x
開始,導致Future[Option[D]]
這個類型的值將是這三個函數的「組合」?
您可以使用單子變壓器(從Scalaz)本:
import scalaz.OptionT
import scalaz.std.option._
import scalaz.syntax.monad._
val result: Future[Option[D]] = (for {
a <- OptionT(x)
b <- OptionT(f1(a).point[Future])
c <- OptionT(f2(b))
} yield f3(c)).run
你需要爲Future
單子實例;有一個在scalaz-contrib中。
這不一定是最好的解決方案,但這是我想出的。 我開始試圖找到一種常見的類型有
type N[X, Y] = Option[X] => Future[Option[Y]]
工作...然後轉換f1
,f2
和f3
於普通型。
val f1: (A => Option[B]) = ???
val f1N: N[A, B] = {
case None => Future.successful(None)
case Some(a) => Future.successful(f1(a))
}
val f2: (B => Future[Option[C]]) = ???
val f2N: N[B, C] = {
case None => Future.successful(None)
case Some(b) => f2(b)
}
val f3: C => D = ???
val f3N: N[C, D] = {
case None => Future.successful(None)
case Some(c) => Future.successful(Some(f3(c)))
}
現在,我已經創建f1N
,f2N
和f3N
,我可以在一個非常漂亮的換理解使用它們。
val y: Future[Option[D]] = for {
aOpt <- x
bOpt <- f1N(aOpt)
cOpt <- f2N(bOpt)
dOpt <- f3N(cOpt)
} yield dOpt
謝謝!如果以下內容看起來像一個愚蠢的問題,我很抱歉:我設法使用'Future {f1(a)}'而不是'f1(a).point [Future]'來編譯它。有什麼區別嗎?我應該使用什麼選項的實施? – miguel
Scalaz包含'Option'的類型類,但我省略了我已修復的導入。你希望使用'Future.successful(f1(a))'(這與'f1(a).point [Future]')相同,而不是'Future {f1(a)}',因爲前者創造一個已經實現的未來,而後者將異步運行'f1(a)',這是不必要的。 – Hugh