Skip to content

Instantly share code, notes, and snippets.

@xuwei-k
Created September 8, 2013 09:20
Show Gist options
  • Save xuwei-k/6483222 to your computer and use it in GitHub Desktop.
Save xuwei-k/6483222 to your computer and use it in GitHub Desktop.
Json4s Scalaz7 example
libraryDependencies ++= Seq(
"org.json4s" %% "json4s-scalaz" % "3.2.5",
"org.json4s" %% "json4s-native" % "3.2.5"
)
scalaVersion := "2.10.2"
/**
* https://github.com/json4s/json4s/issues/39
*
* Validation Monad instance removed from Scalaz7.
* https://github.com/scalaz/scalaz/blob/v6.0.4/core/src/main/scala/scalaz/Validation.scala#L133-L147
*
* need explicitly convert to `scalaz.\/` (aka disjunction) if you want use the `Kleisli` composition
*/
object Main extends App {
import scalaz._
import Scalaz._
import org.json4s.scalaz.JsonScalaz._
import org.json4s._
import org.json4s.native.JsonMethods._
case class Address(street: String, zipCode: String)
case class Person(name: String, age: Int, address: Address)
val json = parse(""" {"street": "Manhattan 2", "zip": "00223" } """)
val address1 = (field[String]("street")(json) |@| field[String]("zip")(json)) { Address }
println(address1)
val address2 = (field[String]("streets")(json) |@| field[String]("zip")(json)) { Address }
println(address2)
val address3 = Address.applyJSON(field[String]("street"), field[String]("zip"))(json)
println(address3)
implicit def addrJSONR: JSONR[Address] = Address.applyJSON(field[String]("street"), field[String]("zip"))
val p = parse(""" {"name":"joe","age":34,"address":{"street": "Manhattan 2", "zip": "00223" }} """)
val person1 = Person.applyJSON(field[String]("name"), field[Int]("age"), field[Address]("address"))(p)
println(person1)
def min(x: Int): Int => Result[Int] = (y: Int) =>
if (y < x) Fail("min", y + " < " + x) else y.success
def max(x: Int): Int => Result[Int] = (y: Int) =>
if (y > x) Fail("max", y + " > " + x) else y.success
type EitherNel[+a] = NonEmptyList[Error] \/ a
val ageValidator1 = Kleisli(field[Int]("age")).mapK[EitherNel, Int](_.disjunction)
val ageValidator2 = {i: Int => (min(18)(i) |@| max(60)(i))((a, _) => a).disjunction}
val ageValidator = ((ageValidator1 >==> ageValidator2).run _).andThen(_.validation)
val person2 = Person.applyJSON(field[String]("name"), ageValidator, field[Address]("address"))
println(person2(p))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment