Ich versuche herauszufinden, wie man dieses Stück Code in einem eleganten pure-funktionalen Stil mit Hilfe von scalaz7 IO und Monade-Transformatoren schreiben kann, aber ich komme einfach nicht dazu.IO und Zukunft [Option] Monade Transformatoren
Man stelle sich vor Ich habe diese einfache API:
def findUuid(request: Request): Option[String] = ???
def findProfile(uuid: String): Future[Option[Profile]] = redisClient.get[Profile](uuid)
diese API verwenden ich unreine Funktion mit OptionT Transformator wie dies leicht schreiben kann:
val profileT = for {
uuid <- OptionT(Future.successful(findUuid(request)))
profile <- OptionT(findProfile(uuid))
} yield profile
val profile: Future[Option[Profile]] = profileT.run
Wie Sie bemerkt haben - diese Funktion enthält findProfile() mit einem Nebeneffekt. Ich möchte diesen Effekt innerhalb der IO-Monade isolieren und außerhalb der reinen Funktion interpretieren, aber ich weiß nicht, wie ich alles kombinieren soll.
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()???
Irgendwelche Tipps, wie es gemacht werden könnte?
Thx @ luka-Jacobowitz Haben Sie Fragen * Ich benutze diesen Code in meiner Spiele-Action.async, also muss ich zurückkehren Zukunft [Ergebnis]. Transforming Task zu scala.Future bedeutet Task Beendigung. Sobald es beendet wird, wird Play's Action synchronisiert. Wissen Sie, wie man eine Aufgabe in eine Zukunft ohne Kündigung umwandeln kann? * Gehen Sie weiter - betrachten Sie IO Monad nur als eine verschobene Berechnung? Wenn es so ist, bedeutet das, dass das ursprüngliche findProfile: Future auch faul ist und die Berechnung in ExecutionContext verschoben wird? In diesem Fall ist es nicht notwendig, Future in IO zu verpacken - diese Funktion ist bereits rein? –
Das Problem mit Future ist, dass es nicht faul ist. Es führt alle Nebenwirkungen aus, die Sie im Futures-Body definieren, wodurch es standardmäßig zu einer unreinen Funktion wird. Sehen Sie hier für mehr darüber: https://www.reddit.com/r/scala/comments/3zofjl/why_is_future_totally_unusable/ Mein Vorschlag wäre, Aufgaben überall zu verwenden und zu oder von Zukunft zu konvertieren, wenn Sie müssen :) –
thank Sie. Habe letzte Nacht im Future/Task-Vergleich geforscht, lies auch diesen Reddit-Beitrag. –