Scala как вызвать будущую функцию для элементов hashmap - PullRequest
0 голосов
/ 04 апреля 2020

У меня есть хэш-карта map: Map[A, Seq[B]], и я хочу вызвать будущую функцию (которая возвращает Future[Either[Error, Unit]]) для каждого B в моей карте.

Например, учитывая следующую функцию def fooFunc(hashMap: Map[A, Seq[B]]): Future[Either[Error, Unit]]

Я пробовал что-то вроде

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
}

, что дает ошибку компиляции Type mismatch, expected: NotInferedM[Future[NotInferedA]], actual: [Future[Either[Error, Unit]]]

This я впервые имею дело с фьючерсами и перебираю hashmap, поэтому я не совсем понимаю, как именно go об этом и иметь дело с Iterable. Любые советы будут оценены

1 Ответ

1 голос
/ 04 апреля 2020

Мы можем нанести на карту HashMap, как и любую другую коллекцию, например List

m.flatMap({ case (key, values) => values.map(f(_, key)) })

, где m: Map[A, Seq[B]] и f: (B, A) => Future[Unit]. Это возвращает Iterable[Future[Unit]], поэтому мы можем использовать Future.sequence для инвертирования в Future[Iterable[Unit]]

m
  .flatMap({ case (key, values) => values.map(f(_, key)) })
  .pipe(Future.sequence(_))

Фьючерсы внутренне представляют успех / неудачу, используя Try, который мы можем преобразовать в Either используя transform и toEither примерно так

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]]

, что возвращает требуемый тип Future[Either[Error, Unit]]. Метод pipe исходит из import util.chaining._

Лично преобразование из Map[A, Seq[B]] в Future[Either[Error, Unit]] выглядит немного подозрительным.

...