Cómo apilar funtores aplicativos en Scala


Los funtores aplicativos se mencionan a menudo como una alternativa a las mónadas cuando sus pasos de cálculo son independientes. Una de sus ventajas a menudo mencionadas es que no necesita transformadores cuando desea apilar aplicativos, porque F[G[X]] siempre es también un aplicativo. Digamos que tengo las siguientes funciones:

def getDataOption(): Option[Data]
def getUserFuture(): Future[User]
def process(data: Data, user: User)

Me gustaría tener un apilamiento elegante para obtener un Future[Option[User]] y Future[Option[Data]] y mapearlo con process.

Hasta ahora solo se me ocurrió esto (usando Gatos):

Applicative[Future]
  .compose[Option]
    .map2(
      Applicative[Future].pure(getDataOption()),
      getUserFuture().map(Applicative[Option].pure))(process)

Pero estoy seguro de que está lejos de ser ideal. ¿Hay una forma más elegante y genérica de lograr lo mismo?

Author: kciesielski, 2016-04-20

1 answers

Lo más difícil es la inferencia de tipos aquí. Esto es lo mejor que pude hacer

  // for the Applicative[Future[Option[?]]
  import cats.Applicative

  implicit val fo = {
    import cats.std.future._
    import cats.std.option._
    Applicative[Future].compose[Option]
  }

  // for the |@| syntax
  import cats.syntax.cartesian._

  // to guide type inference
  type FutureOption[A] = Future[Option[A]]

  ((Future(getDataOption): FutureOption[Data]) |@|
    getUserFuture.map(Option.apply)).map(process _)
 3
Author: Eric,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-04-21 07:11:05