Skip to content

Instantly share code, notes, and snippets.

@loicdescotte
Last active September 30, 2019 13:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save loicdescotte/52aac795c74dfca1cd622d6736abe906 to your computer and use it in GitHub Desktop.
Save loicdescotte/52aac795c74dfca1cd622d6736abe906 to your computer and use it in GitHub Desktop.
Accumulate errors with Either and Cats (based on Cats documentation but with Error ADT and NonEmptyChain)
import cats.implicits._
import cats.data._
import NonEmptyChain._
case class Name(value: String)
case class Age(value: Int)
case class Person(name: Name, age: Age)
trait Error
case object ParsingError extends Error
case class DataValidationError(message:String) extends Error
def parse(s: String): EitherNec[Error, Int] = {
if (s.matches("-?[0-9]+")) Right(s.toInt)
else Left(one(ParsingError))
}
def validateAge(a: Int): EitherNec[Error, Age] = {
if (a > 18) Right(Age(a))
else Left(one(DataValidationError(s"$a is not old enough")))
}
def validateName(n: String): EitherNec[Error, Name] = {
if (n.length >= 8) Right(Name(n))
else Left(one(DataValidationError(s"$n Does not have enough characters")))
}
def parsePerson(nameString: String, ageString: String): EitherNec[Error, Person] =
for {
age <- parse(ageString)
person <- (validateName(nameString), validateAge(age)).parMapN(Person)
} yield person
println(parsePerson("james", "15")) // Left(Chain(DataValidationError(james Does not have enough characters), DataValidationError(15 is not old enough)))
println(parsePerson("james hetfield", "56")) // Right(Person(Name(james hetfield),Age(56)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment