Работа карты короткого замыкания, если попытка не удалась - PullRequest
0 голосов
/ 12 февраля 2020

У меня есть такая функция:

def foo(item: Item) : Option[Int] = Try{
  // Some code that can blow up
}.toOption

У меня есть список предметов, и я хочу отобразить их и применить вышеописанную функцию. Но если вышеприведенная функция взрывается и возвращает None, то результатом карты должно быть сообщение об ошибке:

items.map{
  item => foo(item)
}

Разве карта не подходит для этого? Это не похоже на это

Ответы [ 2 ]

2 голосов
/ 12 февраля 2020

Для готового короткого замыкания рассмотрите обертку отображения списка с Try примерно так

def fooUnsafe(item: Item): Int = // might throw
Try(items.map(fooUnsafe))

Если вы хотите sh сохранить def foo(item: Item) : Option[Int] подпись, тогда следующие также будут короткого замыкания

Try(list.map(v => foo(v).get))
2 голосов
/ 12 февраля 2020

Это называется traverse. Если вы можете использовать cats , это так просто, как:

import cats.implicits._

val result = items.traverse(foo) // Option[List[Int]]

Если нет, вы можете реализовать это довольно легко:

def traverse[A, B](data: List[A])(f: A => Option[B]): Option[List[B]] = {
  @annotation.tailrec
  def loop(remaining: List[A], acc: List[B]): Option[List[B]] =
    remaining match {
      case a :: as => f(a) match {
        case Some(b) => loop(remaining = as, b :: acc)
        case None => None
      }

      case Nil => Some(acc.reverse)
    }

  loop(remaining = data, acc = List.empty)
}

Что вы можете использовать например:

val result = traverse(items)(foo) // Option[List[Int]]

(однако я бы посоветовал вам использовать cats вместо этого, поскольку он более общий) .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...