Skip to content

Instantly share code, notes, and snippets.

@JoolsF
Last active June 2, 2022 21:21
Show Gist options
  • Save JoolsF/189df7d57c52bfe5447ef6b555154338 to your computer and use it in GitHub Desktop.
Save JoolsF/189df7d57c52bfe5447ef6b555154338 to your computer and use it in GitHub Desktop.
Cats validated example 2
import cats.data.Validated
import cats.implicits._
case class User(name: String, age: Int)
type FailFast[A] = Either[List[String], A]
type FailSlow[A] = Validated[List[String], A]
def createUser(html: Map[String, String]): FailSlow[User] =
(
readName(html).toValidated,
readage(html).toValidated
).mapN(User.apply)
def readName(html: Map[String, String]): FailFast[String] =
for {
name <- getValue("name", html)
res <- nonBlank(name)
} yield res
def readage(html: Map[String, String]): FailFast[Int] =
for {
ageStr <- getValue("age", html)
age <- parseInt(ageStr)
res <- ageMustNotBeNegative(age)
} yield res
//Predicates
def ageMustNotBeNegative(age: Int): FailFast[Int] =
Either.cond(age >= 0, age, List(s"Age $age must not be negative"))
def foo(age: Int): FailFast[Int] =
Either.cond(age != -1, age, List(s"Age $age must not be -1"))
def getValue(key: String, html: Map[String, String]): FailFast[String] =
html.get(key).toRight(List(s"Key $key does not exist"))
def parseInt(str: String): FailFast[Int] =
Either.catchOnly[NumberFormatException](str.toInt)
.leftMap(throwable => List(s"$str must be an integer"))
def nonBlank(str: String): FailFast[String] =
Right(str)
.ensure(List(s"$str cannot be blank"))(_.length > 0)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment