alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Lift Framework example source code file (README.md)

This example Lift Framework source code file (README.md) is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Java - Lift Framework tags/keywords

address, fail, int, int, json, jvalue, jvalue, kleisli, result, result, scalaz, string, string, success

The Lift Framework README.md source code

Scalaz support for Lift JSON
============================

This project adds a type class to parse JSON:

    trait JSON[A] {
      def read(json: JValue): Result[A]
      def write(value: A): JValue
    }

    type Result[A] = ValidationNEL[Error, A]

Function 'read' returns an Applicative Functor, enabling parsing in an applicative style.

Simple example
--------------

    scala> import scalaz._
    scala> import Scalaz._
    scala> import net.liftweb.json.scalaz.JsonScalaz._
    scala> import net.liftweb.json._

    scala> case class Address(street: String, zipCode: String)
    scala> case class Person(name: String, age: Int, address: Address)
  
    scala> val json = parse(""" {"street": "Manhattan 2", "zip": "00223" } """)
    scala> (field[String]("street")(json) |@| field[String]("zip")(json)) { Address }
    res0: Success(Address(Manhattan 2,00223))

    scala> (field[String]("streets")(json) |@| field[String]("zip")(json)) { Address }
    res1: Failure("no such field 'streets'")

Notice the required explicit types when reading fields from JSON. The library comes with helpers which
can lift functions with pure values into "parsing context". This works well with Scala's type inferencer:

    scala> Address.applyJSON(field("street"), field("zip"))(json)
    res2: Success(Address(Manhattan 2,00223))

Function 'applyJSON' above lifts function 

    (String, String) => Address 

to

    (JValue => Result[String], JValue => Result[String]) => (JValue => Result[Address])

Example which adds a new type class instance
--------------------------------------------

    scala> implicit def addrJSONR: JSONR[Address] = Address.applyJSON(field("street"), field("zip"))

    scala> val p = JsonParser.parse(""" {"name":"joe","age":34,"address":{"street": "Manhattan 2", "zip": "00223" }} """)
    scala> Person.applyJSON(field("name"), field("age"), field("address"))(p)
    res0: Success(Person(joe,34,Address(Manhattan 2,00223)))

Validation
----------

Applicative style parsing works nicely with validation and data conversion. It is easy to compose 
transformations with various combinators Scalaz provides. An often used combinator is called a Kleisli 
composition >=>.

    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

    // Creates a function JValue => Result[Person]
    Person.applyJSON(field("name"), validate[Int]("age") >=> min(18) >=> max(60))

Installation
------------

Add dependency to your SBT project description:

    val lift_json_scalaz = "net.liftweb" %% "lift-json-scalaz" % "XXX"

Links
-----

* [More examples](https://github.com/lift/framework/tree/master/core/json-scalaz/src/test/scala/net/lifweb/json/scalaz)
* [Scalaz](http://code.google.com/p/scalaz/)
* [Kleisli composition](http://www.haskell.org/hoogle/?hoogle=%28a+-%3E+m+b%29+-%3E+%28b+-%3E+m+c%29+-%3E+%28a+-%3E+m+c%29)

Other Lift Framework examples (source code examples)

Here is a short list of links related to this Lift Framework README.md source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.