Last active
April 23, 2019 17:22
-
-
Save yasuabe/bc9c63add3d87fc6b53d680ac6a7b3ba to your computer and use it in GitHub Desktop.
oop to fp - reader monad
This file contains hidden or 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.syntax.option._ | |
// domain layer ----------------------------------------------------------- | |
import monix.eval.Task | |
import cats.data.ReaderT | |
case class Movie(id: Int, title: String) | |
trait MovieRepo { | |
def getMovie(id: Int): Task[Option[Movie]] | |
} | |
trait UsesMovieRepo { | |
val movieRepo: MovieRepo | |
} | |
// application layer ---------------------------------------------- | |
val db = Map[Int, Movie](42 -> Movie(42, "A Movie")) | |
object MovieRepoImpl extends MovieRepo { | |
def getMovie(id: Int): Task[Option[Movie]] = Task(db.get(id)) | |
} | |
trait MovieServiceEnv extends UsesMovieRepo | |
object MovieServiceEnv extends MovieServiceEnv { | |
val movieRepo = MovieRepoImpl | |
} | |
object MovieService { | |
def getMovie(id: Int): ReaderT[Task, MovieServiceEnv, Option[Movie]] = | |
ReaderT(_.movieRepo.getMovie(id)) | |
} | |
val task1 = MovieService.getMovie(42).run(MovieServiceEnv) | |
// runtime layer ------------------------------------------------- | |
import scala.concurrent.Await | |
import monix.execution.Scheduler.Implicits.global | |
import scala.concurrent.duration._ | |
Await.result(task1.runToFuture, 1.second) | |
// test environment ------------------------------------------------------- | |
object TestEnvironment extends MovieServiceEnv { | |
val movieRepo = new MovieRepo { | |
def getMovie(id: Int): Task[Option[Movie]] = Task(Movie(-1, "Test").some) | |
} | |
} | |
val task2 = MovieService.getMovie(42).run(TestEnvironment) | |
Await.result(task2.runToFuture, 1.second) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment