Como você para de construir uma Opção [Coleção] ao alcançar a primeira Nenhuma?

Ao criar uma coleção dentro de umOption, cada tentativa de tornar o próximo membro da coleção pode falhar, tornando a coleção como um todo uma falha também. Após a primeira falha em fazer um membro, eu gostaria de desistir imediatamente e retornarNone para toda a coleção. Qual é a maneira idiomática de fazer isso no Scala?

Aqui está uma abordagem que eu propus:

def findPartByName(name: String): Option[Part] = . . .

def allParts(names: Seq[String]): Option[Seq[Part]] =
  names.foldLeft(Some(Seq.empty): Option[Seq[Part]]) {
    (result, name) => result match {
      case Some(parts) =>
        findPartByName(name) flatMap { part => Some(parts :+ part) }
      case None => None
    }
  }

Em outras palavras, se houver uma chamada parafindPartByName retornaNone, allParts retornaNone. De outra forma,allParts retorna umSome contendo uma coleção deParts, todos com garantia de validade. Uma coleção vazia está OK.

O acima tem a vantagem de parar de chamarfindPartByName após a primeira falha. Mas ofoldLeft ainda itera uma vez para cada nome, independentemente.

Aqui está uma versão que se destaca assim quefindPartByName retorna umNone:

def allParts2(names: Seq[String]): Option[Seq[Part]] = Some(
  for (name <- names) yield findPartByName(name) match {
    case Some(part) => part
    case None => return None
  }
)

Atualmente, acho a segunda versão mais legível, mas (a) o que parece mais legível provavelmente mudará à medida que tiver mais experiência com o Scala, (b) tenho a impressão de que cedoreturn é desaprovado em Scala, e (c) nenhum parece tornar o que está acontecendo especialmente óbvio para mim.

A combinação de "tudo ou nada" e "desistir da primeira falha" parece um conceito de programação tão básico, eu acho que deve haver um Scala comum ou um idioma funcional para expressá-lo.

questionAnswers(5)

yourAnswerToTheQuestion