Created
July 11, 2016 13:35
-
-
Save MiroslavCsonka/2b21b358aa14cd920d6c4884074735bd to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
case class With[+A, +B](a: A, b: B) | |
case class Pass[A](value: A) extends Result[A] | |
case class Fail(errors: List[String]) extends Result[Nothing] | |
sealed trait Result[+A] { | |
def and[B](that: Result[B]): Result[A With B] = (this, that) match { | |
case (Pass(a), Pass(b)) => Pass(With(a, b)) | |
case (Pass(_), Fail(e)) => Fail(e) | |
case (Fail(e), Pass(_)) => Fail(e) | |
case (Fail(e), Fail(thatE)) => Fail(e ++ thatE) | |
} | |
def map[B](f: A => B): Result[B] = flatMap((a) => Pass(f(a))) | |
def flatMap[B](f: (A) => Result[B]): Result[B] = this match { | |
case Pass(a) => f(a) | |
case Fail(e) => Fail(e) | |
} | |
} | |
def parseInt(number: String): Result[Int] = try { | |
Pass(number.toInt) | |
} catch { | |
case e: NumberFormatException => Fail(List(s"$number is not parsable to int")) | |
} | |
def validatePresence[K](map: Map[K, String], key: K): Result[String] = if (map.isDefinedAt(key)) { | |
Pass(map(key)) | |
} else { | |
Fail(List(s"Key $key is not in the map")) | |
} | |
def validateEmail(email: String): Result[String] = Pass(email) | |
def isAdult(age: Int): Result[Int] = if (age >= 18) { | |
Pass(age) | |
} else { | |
Fail(List("Isnt old enough")) | |
} | |
case class Person(name: String, email: String, age: Int) | |
val form = Map( | |
"email" -> "[email protected]", | |
"age" -> "22", | |
"name" -> "Mirek" | |
) | |
val nameValidation = validatePresence(form, "name") | |
val emailValidation = validatePresence(form, "email").flatMap(validateEmail) | |
val ageValidation = validatePresence(form, "age").flatMap(parseInt).flatMap(isAdult) | |
nameValidation and emailValidation and ageValidation map { | |
case name With email With age => Person(name, email, age) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment