Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
ZIO Prelude validation
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
import zio._
import zio.prelude._
object HelloPrelude extends scala.App :
def parseInt(s: String): Either[Error, Int] =
if (s.matches("-?[0-9]+")) Right(s.toInt)
else Left(ParsingError)
def validateAge(a: Int): Either[Error, Age] =
if (a > 18) Right(Age(a))
else Left(DataValidationError(s"$a is not old enough"))
def validateName(n: String): Either[Error, Name] =
if (n.length >= 8) Right(Name(n))
else Left(DataValidationError(s"$n Does not have enough characters"))
// accumulate data validity errors (parallel validation) :
def validateData(name: String, age: Int): Validation[Error, Person] =
Validation.mapParN(
Validation.fromEither(validateName(name)),
Validation.fromEither(validateAge(age))
) (Person)
// example of mixing monadic error handling and parallel data validation :
def parsePerson(nameString: String, ageString: String): Either[NonEmptyChunk[Error], Person] =
for
age <- parseInt(ageString).left.map(e => NonEmptyChunk(e)) // stop here if there is a parse error
person <- validateData(nameString, age).toEither // accumulate data validity errors here
yield person
def printPerson(name: String, age: String) =
parsePerson(name, age).fold(
errors => println("error : " + errors.mkString(",")),
person => println("success : " + person)
)
printPerson("james", "15") //error : DataValidationError(james Does not have enough characters),DataValidationError(15 is not old enough)
printPerson("james hetfield", "57") // success : Person(Name(james hetfield),Age(57))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment