Tengo un HashMap map: Map[A, Seq[B]]
y quiero llamar a una función futura (que vuelve Future[Either[Error, Unit]]
) para cada uno B
en mi mapa.
Por ejemplo, dada la siguiente función def fooFunc(hashMap: Map[A, Seq[B]]): Future[Either[Error, Unit]]
He intentado algo parecido
def fooFunc(hashMap: Map[A, Seq[B]]): Future[Either[Error, Unit]] = {
val result = for {
_ <- hashMap.map(entry =>
entry._2.map( value =>
Future.sequence(futureFunc(value, entry._1)).liftF
)
)
} yield ()
result.value
}
que da el error de compilación Type mismatch, expected: NotInferedM[Future[NotInferedA]], actual: [Future[Either[Error, Unit]]]
Esta es la primera vez que se trata de futuros y la iteración en HashMap, así que estoy confundido cómo ir exactamente sobre esto y trato con el Iterable. Cualquier extremidad sería apreciada
Podemos asignar más de una HashMap
al igual que cualquier otra colección comoList
m.flatMap({ case (key, values) => values.map(f(_, key)) })
donde m: Map[A, Seq[B]]
y f: (B, A) => Future[Unit]
. Esto devuelve Iterable[Future[Unit]]
por lo que podemos utilizar Future.sequence
para invertir aFuture[Iterable[Unit]]
m
.flatMap({ case (key, values) => values.map(f(_, key)) })
.pipe(Future.sequence(_))
Los futuros representan internamente éxito / fracaso mediante Try
el cual podemos convertir a Either
utilizar transform
y toEither
como tal
m // : Map[A, Seq[B]]
.flatMap({ case (key, values) => values.map(f(_, key)) }) // : Iterable[Future[Unit]]
.pipe(Future.sequence(_)) // : Future[Iterable[Unit]]
.map(_ => ()) // : Future[Unit]
.transform(tryResult => Success(tryResult.toEither)) // : Future[Either[Throwable, Unit]]
que devuelve la requerida Future[Either[Error, Unit]]
tipo. El pipe
método proviene deimport util.chaining._
En lo personal, la transformación de Map[A, Seq[B]]
a Future[Either[Error, Unit]]
, se siente un poco sospechoso.