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

Write yourself KVO in Swift

KVO is a major part of Objective-C dynamic nature. Having virtually every property or ivar observable by its key path opens doors to simple bindings or advanced technologies like ReactiveCocoa. But what about Swift? It’s static nature... Continue →