In my code, I very often need to process a list by performing operations on an internal model. For each processed element, the model is returned and then a 'new' model is used for the next element of the list.
Usually, I implement this by using a tail recursive method:
def createCar(myModel: Model, record: Record[Any]): Either[CarError, Model] = {
record match {
case c: Car =>
// Do car stuff...
val newModel: Model = myModel.createCar(record)
Right(newModel)
case _ => Left(CarError())
}
}
@tailrec
def processCars(myModel: Model, records: List[Record[Any]]): Either[CarError, Model] =
records match {
case x :: xs =>
createCar(myModel, x) match {
case Right(m) => processCars(m, xs)
case e@Left(_) => e
}
case Nil => Right(myModel)
}
Since I keep repeating this kind of pattern, I am searching for ways to make it more concise and more functional (i.e., the Scala way).
I have looked into foldLeft
, but cannot get it to work with Either
:
recordsList.foldLeft(myModel) { (m, r) =>
// Do car stuff...
Right(m)
}
Is foldLeft
a proper replacement? How can I get it to work?