J'essaie de trouver comment écrire ce morceau de code dans un style élégant et purement fonctionnel en utilisant scalaz7 IO et les transformateurs de monades, mais je n'arrive pas à m'y retrouver.
Imaginez que j'ai cette simple API :
def findUuid(request: Request): Option[String] = ???
def findProfile(uuid: String): Future[Option[Profile]] = redisClient.get[Profile](uuid)
En utilisant cette API, je peux facilement écrire une fonction impure avec le transformateur OptionT comme ceci :
val profileT = for {
uuid <- OptionT(Future.successful(findUuid(request)))
profile <- OptionT(findProfile(uuid))
} yield profile
val profile: Future[Option[Profile]] = profileT.run
Comme vous l'avez remarqué - cette fonction contient findProfile() avec un effet de bord. Je veux isoler cet effet à l'intérieur de la monade IO et l'interpréter à l'extérieur de la fonction pure, mais je ne sais pas comment combiner le tout.
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()???
Des conseils sur la manière de procéder ?