Writings on software engineering.
Back in my first Chiron article, I made a bit of a mistake. I started with all the things
that scare off new functional programmers. Things like >>=
and monads. We're going to take a step
back from that precipice and talk about the json{}
computation expression.
In general, computation expressions are a bit of syntactic sugar that F# provides. Internally, the
monadic functions of Bind
and Return
are used, but that is generally transparent to the
user of a computation expression.
Let's dive straight into an example from the first article:
1: 2: 3: |
|
Now, using the json{}
compuation expression, let's add the ToJson
and FromJson
functions:
1: 2: 3: 4: 5: 6: 7: 8: 9: |
|
Compared to the previous example, I think this is way more understandable on its face.
There are no custom operators to figure out, and you don't need to open Chiron.Operators
to use it.
So, what do the various parts mean? What's that let!
and do!
? For a fuller explanation of computation
expressions in general, I'll point you to the excellent introduction by Scott Wlaschin on fsharpforfunandprofit.com.
Nonetheless, let's briefly break this down.
1:
|
|
The first line that we will look at is from the FromJson
function. In this case, we are reading the name
member
from the hidden Json
object. This deserialization may or may not be successful. Presuming that it is successful, we
want the value to be bound to n
, but if it fails, we want to short-circuit and report the error.
The key to making this work is the !
in let!
. The !
provides a signal to the F# compiler that what we really want
is the string
from the Json<string>
returned by Json.read
. Chiron's json{}
implementation of provides such a
bind
function which takes care of unwrapping the deserialized value, or in case deserialization fails, triggers the
short-circuit to return the deserialization error.
1:
|
|
Things are subtly different in the ToJson
function. In this case, we are updating the hidden Json
object being
held by the computation expression. The write doesn't return anything meaningful but it does have a return type of
Json<unit>
. The above is syntactically equivalent to:
1:
|
|
The do!
just plain looks better than binding to an ignored value.
In the long-promised next article, we'll finally delve into dealing with missing data and union types.