We’ll try to parse the following basic JSON object into a Swift model.
Before jumping into actual parsing, we need to understand what Currying is.
From Wikipedia: In mathematics and computer science, currying is the technique of translating the evaluation of a function that takes multiple arguments (or a tuple of arguments) into evaluating a sequence of functions, each with a single argument
Currying is a process splitting a function that takes N arguments into N-1 smaller functions (or nested closures in this case) that take 1 argument each. Lets take the initializer function for our Person struct:
So, to create a Person Object, we need to pass both name and age to init method. Here is how it’s curried version looks like.
If you can understand the above code snippet, that’s all there is to Currying.
Now that we understand what Currying is, let’s parse some JSON.
Parsing - Attempt 1
That is too much code just to parse a model with two properties. We can do better by identifying the repeated chunks of code and splitting them into functions.
Parsing - Attempt 2
Code for “extracting values from a dictionary as a specific type” is converted in to individual functions int(:key:) and string(:key:).
The code for those two functions is the same except the types. We can use Generics to make it into a single function.
Parsing - Attempt 3
We created get method using Generic type T, but where are we passing the type?
If you look closely, the type, T, is being inferred from the variable it is being assigned to. The type inferencing is an awesome thing in Swift.
We got the code into a good shape but, still there are two guard statements doing absolutely the same thing and we haven’t used our curried function yet. So, let’s rewrite the code with if-lets and makePerson function.
Parsing - Attempt 4
At first glance, it might look like we made it even worse than previous version. But we can observe a pattern now.
We have a function makePerson aka., f, an optional value aka., x and we perform f(x) only if the optional value is present.
Let’s define a custom operator <*> that does this.
Parsing - Attempt 5
There you have it, JSON dictionary being decoded beautifully into a Swift model.