Given the following types:
sealed trait Pet {
val name: String
}
case class Dog(override val name: String) extends Pet
case class Cat(override val name: String) extends Pet
sealed trait Error
case object DBConnection extends Error
case object NoResults extends Error
We write a function that searches for a pet by its name.
def foo(petName: String): Either[Error, Pet] = {
val results: Either[Error, List[Pet]] = ??? // does not matter
val foundPet: Option[Pet] = results match {
case left @ Left(_) => None
case Right(ps) => ps.find(_.name == petName)
}
foundPet match {
case None => Left(NoResults)
case Some(p) => Right(p)
}
}
Please ignore any improvements to the above code with respect to the database call.
Ideally, I'd prefer to write the above code as a simple for comprehension
, taking advantage of the Either
monad. The pattern matching is easy to read, I believe, but the for
alternative would be more concise, I suspect.
How would I re-write the above code with a for-comprehension? I suppose that I could just make methods that match the return type of Either[Error, Pet]
, but was not sure.