JSON mapping and reader monad [DRAFT]

Functional JSON mapping became a hot theme recently. Clear declarative syntax backed by cryptic concepts of monads and applicative functors has exploded many heads.
I’d like to talk about a little refinement of our mapping pattern to better isolate mapping algorithms from actual data.

Let’s start with some simple mapping code:

struct User {
let name: String
let age: Int

static func build(name: String)(age: Int) -> User {
    return User(name: name, age: age)
}

}

// TODO: write operators

let JSON = [“name”: “Sergei”, “age”: 30]
let user = User.build >> stringForKey(JSON, “name”)
>>> intForKey(JSON, “age”)

The thing that bothers me is coupling of input JSON with our mapping logic. What if we could rectify our mapping to remove this dependency?

Let’s introduce a Reader monad. The simple idea behind is expressing our computation as a function of our JSON parameter and once we need it, “running” it bound with data.

struct Reader {
let value: T -> U

func run(t: T) -> U {
    return value(t)
}

}

Here we express some value U as a function of T and store it in a type safe manner. Here’s how we use it:

func intForKey(key: String) -> Reader {
return Reader({ $0[key] as? Int })
}

See how our dependency on JSON is extracted and moved somewhere to a future?

Once we redefine our lifting and binding operators for Reader<>, we end up with the same mapping code:

let parse = User.build >> stringForKey(JSON, “name”)
>>> intForKey(JSON, “age”)

The only difference is it returns Reader instead of User?. To get User we need to bind it with JSON:

let user = parse.run(JSON)

This approach greatly facilitated code reuse via enabling to define algorithms instead of plain transforms on data.

 
0
Kudos
 
0
Kudos

Now read this

How to use your own frameworks in Swift playgrounds

With the new beta of Xcode Apple added support for importing custom frameworks to Swift Playgrounds. Let’s explore the way to use them. We’ll start with a new Cocoa Touch Framework project: Let’s call it MyFramework. I have selected... Continue →