final case class Person(name: String, age: Int) final class EmptyNameException(message: String) extends Exception(message) final class InvalidAgeException(message: String) extends Exception(message) // with Exceptions def getName(providedName: String) : String = { if (providedName.trim.isEmpty) throw new EmptyNameException(s"provided name is empty") else providedName.trim } def getAge(providedAge: String) : Int = { try { val age = providedAge.toInt if (age >= 1 && age <= 120) age else throw new InvalidAgeException(s"provided age is invalid: ${providedAge}") } catch { case e: NumberFormatException => throw new InvalidAgeException(s"provided age is invalid: ${providedAge}") } } //throws EmptyNameException, InvalidAgeException def createPerson(name: String, age: String): Person = { Person(getName(name), getAge(age)) } val validPairs: List[(String, String)] = personStringPairs.filter { case (name, age) => try { createPerson(name, age) true } catch { case e: EmptyNameException => false //if we forget to check for one of these, an Exception is thrown case e: InvalidAgeException => false } } //no type-validation that these are "valid" Strings. validPairs.map(Function.tupled(createPerson)) // with Eithers def getName2(providedName: String): Either[String, String] = { if (providedName.trim.isEmpty) Left(s"provided name empty") else Right(providedName.trim) } def getAge2(providedAge: String): Either[String, Int] = { try { val age = providedAge.toInt if (age >= 1 && age <= 120) Right(age) else Left(s"provided age is invalid: ${providedAge}") } catch { case e: NumberFormatException => Left(s"provided age is invalid: ${providedAge}") } } def createPerson2(name: String, age: String): Either[String, Person] = { for { pName <- getName2(name) pAge <- getAge2(age) } yield Person(pName, pAge) } personStringPairs.map(Function.tupled(createPerson2)).collect { case Right(p) => p } // test data //given a List of String pairs representing names and ages: val personStringPairs = List(("Tokyo", "30"), ("Moscow", "5o"), ("The Professor", "200"), ("Berlin", "43"), ("Arturo Roman", "0"), ("", "30")) // create a List of only valid Person instances