Last active
July 25, 2019 09:41
-
-
Save taisukeoe/a23fda864c2b6964e004bada75712807 to your computer and use it in GitHub Desktop.
Reader[Future[X]]をうまく扱うためには、ReaderTでいいと思うよ (248回 rpscalaのフォローアップ)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import cats._ | |
import cats.data.{Kleisli, Reader, ReaderT} | |
import cats.implicits._ | |
import scala.concurrent.{ExecutionContext, Future} | |
object ReaderStyle extends App { | |
def someCalc(i: Int): Int = ??? | |
import ExecutionContext.Implicits.global | |
val future = Reader { i: Int => Future(someCalc(i)) } | |
/* | |
xもyもFuture[Int]型なので、 `+` できない。(コンパイル通らない)。 | |
for { | |
x <- future | |
y <- future | |
} yield x + y | |
ReaderにはTraverse型クラスのインスタンスがないので、FutureがApplicativeでもsequenceしてFuture[Reader[Int]]を得ることもできない | |
future.sequence | |
*/ | |
val futureReaderT = ReaderT { i: Int => Future(someCalc(i)) } | |
//Reader Monad Transformerを使うと、map / flatMapで中身(この場合はInt)を取り出せる | |
val composedFutureReaderT = for { | |
x <- futureReaderT | |
y <- futureReaderT | |
} yield x + y | |
//Reader[Int, Future[Int]のように、applyでIntの値を注入できる | |
composedFutureReaderT(100) | |
//ReaderTはただの型エイリアスで、その実態はモナドを作る関数のラッパーであるKleisli | |
//val futureKleisli = Kleisli { i: Int => Future(someCalc(i)) } | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
さらにEitherTを積みたい場合はこう?
ReaderTの実態はKleisliなので、他のMonadTransformerに比べると複数積み上げしやすいだろうか。
(Eff案件かな?)