Skip to content

Instantly share code, notes, and snippets.

@yasuabe
Last active Apr 23, 2019
Embed
What would you like to do?
oop to fp - reader monad
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