2015-04-14 3 views
1

Учитывая список входов, которые могут быть действительными или недействительными, есть хороший способ преобразовать список, но сбой при получении одного или нескольких недопустимых входов и, при необходимости, для возврата информации о эти недействительные входы? У меня есть что-то вроде этого, но он чувствует себя очень неэлегантно.Как лучше разделить допустимые или недопустимые входы

def processInput(inputList: List[Input]): Try[List[Output]] = { 
    inputList map { input => 
     if (isValid(input)) Left(Output(input)) 
     else Right(input) 
    } partition { result => 
     result.isLeft 
    } match { 
     case (valids, Nil) => 
      val outputList = valids map { case Left(output) => output } 
      Success(outputList) 
     case (_, invalids) => 
      val errList = invalids map { case Right(invalid) => invalid } 
      Failure(new Throwable(s"The following inputs were invalid: ${errList.mkString(",")}")) 
    } 
} 

Есть ли лучший способ сделать это?

ответ

2

Я думаю, вы можете упростить текущее решение совсем немного со стандартным Скале:

def processInput(inputList: List[Input]): Try[List[Output]] = 
    inputList.partition(isValid) match { 
    case (valids, Nil) => Success(valids.map(Output)) 
    case (_, invalids) => Failure(new Throwable(s"The following inputs were invalid: ${invalids.mkString(",")}")) 
    } 

Или у вас может быть довольно элегантное решение с scalactic's Or.

import org.scalactic._ 

    def processInputs(inputList: List[Input]): List[Output] Or List[Input] = 
    inputList.partition(isValid) match { 
    case (valid, Nil) => Good(valid.map(Output)) 
    case (_, invalid) => Bad(invalid) 
    } 

В результате типа org.scalactic.Or, которые вы затем должны соответствовать к Good или Bad. Этот подход более полезен, если вам нужен список недопустимых входов, вы можете сопоставить его с Bad.

2

Проверка подлинности scalaz разработана именно для этого. Попробуйте прочитать в tale of three nightclubs для того, как это будет работать, но тело вашей функции, вероятно, в конечном итоге просто состоящий из чего-то вроде:

def processInput(inputList: List[Input]): Validation[List[Output]] = { 
    inputList foldMap { input => 
    if (isValid(input)) Failure(Output(input)) 
    else Success(List(input)) 
}