私はこのコードをscalaz7 IOとモナド変圧器を使ってエレガントな純粋な関数形式で書く方法を考え出していますが、頭をかぶっていません。この関数はfindProfileが含まれている -IOとFuture [オプション]モナド変換器
あなたが気づいたようval profileT = for {
uuid <- OptionT(Future.successful(findUuid(request)))
profile <- OptionT(findProfile(uuid))
} yield profile
val profile: Future[Option[Profile]] = profileT.run
:私は簡単にこのようなOptionT変圧器と不純な関数を書くことができ、このAPIを使用して
def findUuid(request: Request): Option[String] = ???
def findProfile(uuid: String): Future[Option[Profile]] = redisClient.get[Profile](uuid)
:
はちょうど私がこの単純なAPIを持っている想像します()に副作用があります。私はIOモナドの内部でこの効果を分離し、純粋な機能の外で解釈したいが、すべてを一緒に組み合わせる方法を知らない。
def findProfileIO(uuid: String): IO[Future[Option[Profile]]] = IO(findProfile(uuid))
val profileT = for {
uuid <- OptionT(Future.successful(findUuid(request)))
profile <- OptionT(findProfileIO(uuid)) //??? how to put Option inside of the IO[Future[Option]]
} yield profile
val profile = profileT.run //how to run transformer and interpret IO with the unsafePerformIO()???
どうすればよいですか?
のTHX @のルカ・Jacobowitzさんが質問をお持ちの *私は自分のプレイのAction.asyncの内側にこのコードを使用するので、私は返す必要が未来[結果]。タスクをscalaに変換する。将来はタスクの終了を意味する。それが終了するとすぐに、プレイのアクションは同期になります。終了せずにタスクを未来に変換する方法を知っていますか? *さらに進んでいます - IO Monadは延期された計算のみと考えていますか?それがそうであれば、元のfindProfile:Futureもまた怠惰で、ExecutionContextでの計算も延期されていることを意味しますか?この場合、IOをFutureにラップする必要はないかもしれません - この関数はすでに純粋ですか? –
未来の問題は、それが怠惰ではないということです。 Futures本体内で定義した副作用はすべて実行され、デフォルトでは不正な機能になります。詳細についてはこちらをご覧ください:https://www.reddit.com/r/scala/comments/3zofjl/why_is_future_totally_unusable/ 私の提案は、どこからでもタスクを使用して、未来に変換することです: –
ありがとう君は。昨夜、未来/仕事の比較に掘り起こして、このreddit投稿を読んでみてください。 –