I am trying to figure out how to write this piece of code in an elegant, clean, functional style using floating point converters and monad transformers, but just can't get it around.
Just imagine that I have this simple API:
def findUuid(request: Request): Option[String] = ???
def findProfile(uuid: String): Future[Option[Profile]] = redisClient.get[Profile](uuid)
Using this API, I can easily write an impure function with an OptionT transformer as follows:
val profileT = for {
uuid <- OptionT(Future.successful(findUuid(request)))
profile <- OptionT(findProfile(uuid))
} yield profile
val profile: Future[Option[Profile]] = profileT.run
As you noticed, this function contains findProfile () with a side effect. I want to isolate this effect inside the IO monad and interpret it outside a pure function, but I don’t know how to combine all this together.
def findProfileIO(uuid: String): IO[Future[Option[Profile]]] = IO(findProfile(uuid))
val profileT = for {
uuid <- OptionT(Future.successful(findUuid(request)))
profile <- OptionT(findProfileIO(uuid))
} yield profile
val profile = profileT.run
How many tips on how to do this?
source
share