scala - validated - cats core
Cómo apilar funtores aplicativos en Scala. (1)
Los funtores aplicativos se mencionan a menudo como una alternativa a las mónadas cuando sus pasos de cómputo son independientes. Una de las ventajas que a menudo se mencionan es que no necesita transformadores cuando desea apilar aplicativos, porque F[G[X]]
también es siempre 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 un Future[Option[Data]]
y mapear eso con el 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?
Lo más difícil es la inferencia de tipo 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 _)