Our journey starts with this problem: we want to count the number of leaves of an arbitrary Binary Tree. To keep the problem as simple as possible, we define a Binary Tree as that data structure having Nodes and Leaves, and in which every Node has exactly two branches.
This is a Tree with 2 Leaves:
Node
/ \
Leaf Leaf
and here is a Tree with 3 Leaves:
Node
/ \
Leaf Node
/ \
Leaf Leaf
It is legit to ask ourselves: is a single Leaf a Tree?
Leaf
Let’s agree that it is.
Do null Trees — Trees without Nodes and Leaves — exist?
Let’s do ourselves a favor and agree they don’t.
A Node always contains 2 Leaves. What does a Leaf contain? Nothing: it
just is.
So, a Tree is either a Leaf or a Node made of 2 branches, each
containing another Tree structure. Remember this definition, because
we will translate it more or less literally to F#.
How deep can such Binary Trees be? Arbitrarily deep. For example, this is a legit Tree:
Node
/ \
Leaf Node
/ \
Node Leaf
/ \
Leaf Node
/ \
Node Leaf
/ \
Leaf Node
/ \
Leaf Leaf
Of course, our code should work with any Tree, no matter how deep.
Good. We are diligent developers, so we start from a test. To keep it simple, let’s count the Leaves of a 3leaves Tree:
module StateMonadTest
open Xunit
open Swensen.Unquote
let numberOfLeaves tree = failwith "Not yet implemented"
[<Fact>]
let ``counts the number of leaves in a tree`` () =
let treeWith3Leaves = failwith "Not yet implemented"
let leaves = numberOfLeaves treeWith3Leaves
test <@ leaves = 3 @>
Let’s fill the gaps. As often happens with Functional Programming, it is convenient to start from modeling problems through their types.
How to model a Tree? That’s an easy task in F#: it’s a matter of translating literally our definition:
A Tree is either a Leaf or a Node containing 2 branches each containing another Tree structure.
Step by step:
A Tree is
is simply translated totype Tree =
be a Leaf
:type Tree = Leaf
or a Node
. The or
part is translated with the 
operator:type Tree = Leaf  Node ???
contains
2
branches. The contain part is translated with
of
, the multiplicity is translated with *
:type Tree = Leaf  Node of (??? * ???)
Tree
itself. So:type Tree = Leaf  Node of (Tree * Tree)
That’s it!
As an aside, this expression makes use of the so called Algebraic Data
Types, which include Sum (or Discriminated Union) Types and Product Types.
Name  Symbol used  Equivalent technique in OOP 

Sum Types   
Inheritance 
Product Types  * 
Multiple fieds in classes 
In C# this would approximately translate to:
abstract record Tree;
record Leaf : Tree;
record Node(Tree Left, Tree Right) : Tree;
In both cases, we have a recursive type, which both languages happily support.
Creating instances in F# is similar, but more concise, than in C# and
Java: you just have to omit the new
keyword and the parenthesis.
Our 3leaves tree:
Node
/ \
Leaf Node
/ \
Leaf Leaf
can be created with:
let treeWith3Leaves = Node(Leaf, Node(Leaf, Leaf))
This completes the test implementation:
[<Fact>]
let ``counts the number of leaves in a tree`` () =
let treeWith3Leaves = Node(Leaf, Node(Leaf, Leaf))
let leaves = numberOfLeaves treeWith3Leaves
test <@ leaves = 3 @>
Good. Now, let’s see how to make it green.
It is important to understand that in:
type Tree = Leaf  Node of (Tree * Tree)
Tree
is a type, Leaf
and Node
are not: Leaf
and Node
are
ways for creating an instance of type Tree
. This is akin to the
difference between a class and its constructors. In F#, we would call
Tree
, Leaf
and Node
as follows:
Element  Name 

Tree 
Discriminated Union Type 
Leaf and Node of (Tree * Tree) 
Union Case 
Haskell uses different names, but the meaning is the same:
Element  Name 

Tree 
Type Constructor 
Leaf and Node Tree Tree 
Data Constructor 
We will shortly see why Tree
is a Type Constructor, not just a
Type: as soon as Tree
will take a (type) parameter, we will learn to
see it more as a function than just a type name.
The takeaway here is: given an instance of Tree
, F# can pattern
match on the Case which was used to create the instance. It’s like
the instance remembers which constructor was used to create it. You
can read more about it in Pattern Matching  Identifier Patterns.
This give you all the ingredients to develop a function to calculate the number of leaves.
Pattern matching is easy:
let numberOfLeaves tree =
match tree with
 Leaf > ???
 Node (l, r) > ???
Read it as a glorified if/then/else
and ask yourself:
numberOfLeaves
receives a tree, and that tree is a single
Leaf
, how many leaves does that tree have? In other words, the
function needs to calculate the number of leaves of this tree: Leaf
Of course, it has just 1
leaf! So:
let numberOfLeaves tree =
match tree with
 Leaf > 1
 Node (l, r) > ???
What about if tree
is a Node
? You only know that a Node
contains
exactly 2
branches. Each branch could be a Leaf, like in:
Node
/ \
Leaf Leaf
or it could be another arbitrarily deep tree, like in:
Node
/ \
Leaf Node
/ \
Node Leaf
/ \
Leaf Node
/ \
Node Leaf
/ \
Leaf Node
/ \
Leaf Leaf
In the general case, you can see the received tree as:
Node
/ \
Tree Tree
This node contains as many leaves as the leaves in the right branch tree, plus the leaves of the left branch tree. Literally translating this sentence to F# leads us to:
let rec numberOfLeaves tree =
match tree with
 Leaf > 1
 Node (l, r) > numberOfLeaves l + numberOfLeaves r
Notice that we added the keyword rec
to the function definition, to
make it clear that the function is recursive.
Does this work? You have a test. Run it.
Of course it’s green. As it often happens, if it compiles it works.
Get used to this, it will happen over and over.
Let’s review what you obtained:
type Tree =
 Leaf
 Node of Tree * Tree
let rec numberOfLeaves tree =
match tree with
 Leaf > 1
 Node(l, r) > numberOfLeaves l + numberOfLeaves r
[<Fact>]
let ``counts the number of leaves in a tree`` () =
let treeWith3Leaves = Node(Leaf, Node(Leaf, Leaf))
let leaves = numberOfLeaves treeWith3Leaves
test <@ leaves = 3 @>
You can see how the:
 Leaf > 1
branch is the base case of recursion, while the:
 Node(l, r) > numberOfLeaves l + numberOfLeaves r
is the (double) recursive step.
Also notice how the results of the 2 recursive calls are composed
with the binary +
function.
In:
let rec numberOfLeaves tree =
match tree with
 Leaf > 1
 Node(l, r) > numberOfLeaves l + numberOfLeaves r
the parameter tree
is only used to pattern match. To stress this, F#
provides an alternative, more concise syntax, where
... tree =
match tree with
is replaced by:
... function =
So, our function can be made shorter, as:
let rec numberOfLeaves =
function
 Leaf > 1
 Node(l, r) > numberOfLeaves l + numberOfLeaves r
A nice way to interpret this is to squeeze the eyes and imagine it’s a
combination of 2 separate function definitions, one on Leaf
and one
on Node(l, r)
. Haskell would really let you define 2 separate functions:
numberOfLeaves Leaf = 1
numberOfLeaves Node(l, r) = numberOfLeaves l + numberOfLeaves r
If you manage to understand this last snippet, bravo!, give yourself a pat on the back, take a little breather, and get prepared to the next chapter, in which you will invent (or discover) Functors.
Jump to Chapter 2.
Interested in FP? Be the first to be notified when new introductory
articles on the topic are published.
In chapter 7, when we wanted to
introduce a new type for the result value of index
:
// Tree a > (Int > (Tree (a, Int), Int))
let rec index =
function
 Leaf v > fun count > (Leaf (v, count), count + 1)
 Node (l, r) >
fun count >
let li, lc = index l count
let ri, rc = index r lc
Node (li, ri), rc
I mentioned that there was a second perspective, leading to the same
signature of WithCount
:
count
handling and domain
logic on the type level.Let us do this, because it will lead to some interesting refinements
Observing again the original signature:
Tree a > (Int > (Tree (a, Int), Int))
it’s not hard to see what happened. Ideally, you wanted a simple function:
Tree a > Tree (a, Int)
taking a tree of whatever content and returning an indexed version of it. This is the original domain logic, which you can easily make more generic with:
a > (a, Int)
Then, you wanted to have a Functor to take care of the logic for
traversing a tree. But then you found out that Functors are not
powerful enough to apply an indexing function with map
.
Instead of that, you ended up with:
Pure logic  What you got 

Tree a > Tree (a, Int) 
Tree a > (Int > (Tree (a, Int), Int)) 
or, generalizing:
Pure logic  What you got 

a > b 
a > (Int > (b, Int)) 
Squint the eyes. This expression contains the domain logic and the counthandling logic mixed together. Let me move the counthandling logic to a separate line:
Tree a > Tree (a, Int)
(Int > ( , Int))
or if you want to make to use the more generic version:
a > b
(Int > ( , Int))
The:
Int > (b, Int)
captures exactly what you did in chapter 6:
What you did  

You return a function getting the previous count value 
Int 

You return the domain logic result plus the next count value 
> (b, Int) 
If you want to give this idea a name, and capture it with a type, it makes sense to defind it with:
type WithCount<'b> = WithCount of (int > 'b * int)
Of course, this could be more specific to trees:
type WithCount<'b> = WithCount of (int > Tree<'b> * int)
or even more specif to our indexing usecase:
type WithCount = WithCount of (int > Tree<string, int> * int)
but why should it be? On the contrary, it could be generic also on the type of the counter:
type WithCount<'b, 'c> = WithCount of ('c > 'b * 'c)
where 'c
is the type of the state being chained, and 'b
is the
original domain logic result type.
c
is not a count anymore, it’s a generic state. Let’s call it s
.
And WithCount
is a misleading name. We can easily call it State
:
type State<'b, 's> = State of ('s > ('b * 's))
This generalized version of WithCount
is, ladies and gentlemen, the
signature of the State Monad.
It’s definitely the time to implement it. Ready! Steady! Go with
Chapter 11!
Two chapters ago, you wrote the
applicative version of index
using <*>
and <*
. If you remember,
in chapter 8 we said that there
are 2 different series of moves:
You performed the former, which were:
WithCount
.Now we try another approach:
WithCount
value.Let’s follow this path.
This is the starting point:
let rec index =
function
 Leaf v >
WithCount(fun count >
(buildLeaf v count, count + 1))
 Node(l, r) >
WithCount(fun count >
let li, lc = run (index l) count
let ri, rc = run (index r) lc
(buildNode li ri), rc)
Focusing on the Node
branch, the function we want to modify is
buildNode
. So far, it returns a Node
: let it return a WithCount
instead:
let rec index =
function
 Node(l, r) >
// Tree a > Tree a > WithCount (Tree a)
let buildNode' l r = pure' (buildNode l r)
The problem now is how to feed it with WithCount
values. In fact,
once recursing on index
on l
and r
you get:
 Node(l, r) >
// WithCount (Tree a)
let li = index l
// WithCount (Tree a)
let ri = index r
// Tree a > Tree a > WithCount (Tree a)
let buildNode' l r = pure' (buildNode l r)
You cannot just pass li
and ri
to buildNode'
:
// Tree a > Tree a > WithCount (Tree a)
let buildNode' l r = pure' (buildNode l r)
buildNode' li ri
the compiler would complain because buildNode'
expects naked Tree
values, and you are providing promises of them. F#’s builtin function
application is not smart enough to handle WithCount
instances. But
you can easily teach it.
Just like you did before with the Applicative Functor, it’s a matter
of implementing another onsteroids function application, one which is
able to provide WithCount
arguments to functions expecting naked values.
Here’s the general challenge:
a :: Tree a
.f :: Tree a > WithCount (Tree b)
.f a
.f ??? a
able to do that.Yes, in the Node
branch you have a 2
parameter function, but as
usual you will find that solving the problem for 1
parameter
functions scales to any n
parameter ones. The power of currying…
Implementing this onsteroids function application, that we will call
=<<
(pronunced “reversed bind”) is actually simple. It is similar to
what you have alread done in Chapter
3 to implement map
, using the box
metaphor. Be guided by types: they will lead you to the correct
implementation
// (a > WithCount b) > WithCount a > WithCount b
let (=<<) f a =
???
If only a
was a naked instance of a
, you could feed it directly to
f
. But it is not: it is a (WithCount
wrapped) function, waiting
for a count
to return a naked a
instance. You could pass it a
count
instance. Sure: but where to find it? Can you produce it one
out of thin air?
Actually you can. Remember my trick: when you don’t have a value,
defer the problem and return a function asking for it.
Another way to see this is: consider that you will finally have to
return another WithCount
value. So it makes sense to start building
one:
// (a > WithCount b) > WithCount a > WithCount b
let (=<<) f a =
WithCount ???
And you know that a WithCount
contains a function from count
:
// (a > WithCount b) > WithCount a > WithCount b
let (=<<) f a =
WithCount (fun count > ???)
Here’s the count
value you needed. With it, you can ask a
to
generate a naked value. How? But with run
, the function you have
already created to run a WithCount
:
// WithCount v > Int > v
let run (WithCount f) (count: int) = f count
// (a > WithCount b) > WithCount a > WithCount b
let (=<<) f a =
WithCount (fun count >
// (a, Int)
let va, ca = run v count
???)
va
is the naked a
value; ca
is the count. Perfect: you can
finally feed f
:
// (a > WithCount b) > WithCount a > WithCount b
let (=<<) f a =
WithCount(fun count >
let va, ca = run a count
let result = f vv
Which type is result
? It matches the return value of the f
signature, so it is a WithCount b
. Your code already lives inside a
WithCount
, you don’t need to nest another one. You know that in
order to extract a naked value from a WithCount
, you can run it
providing it a value of count
. In this case, you have a freshly
calculated, unused ca
:
// (a > WithCount b) > WithCount a > WithCount b
let (=<<) f a =
WithCount(fun count >
let va, ca = run a count
let result = f vv
run result ca)
Since the name of =<<
is “reversed bind”, you might have guessed
that a forwardversion also exist. In fact, as you will soon find out,
is convenient to flip the arguments. Let’s define a specular >>=
operator, called “bind”. Just flip the parameters, reusing the very
same implementation:
// WithCount a > (a > WithCount b) > WithCount b
let (>>=) a f =
WithCount(fun count >
let va, ca = run a count
let result = f va
run result ca)
Of course, since you abhor copypasting, you can redefine =<<
in
terms of >>=
just flippling the parameters:
// (a > WithCount b) > WithCount a > WithCount b
let (=<<) a b = b (>>=) a
Let’s put this bind operator at work!
>>=
You have all the ingredients: li
, the indexed left branch, which is
a WithCount Tree a
value, and buildNode'
, which expects a naked
Tree a
value. Feed it with >>=
:
let rec index =
function
 Node(l, r) >
// WithCount (Tree a)
let li = index l
// WithCount (Tree a)
let ri = index r
// Tree a > Tree a > WithCount (Tree a)
let buildNode' l r = pure' (buildNode l r)
li >>= ???
Read the >>=
signature again:
// WithCount a > (a > WithCount b) > WithCount b
let (>>=) a f = ...
On the right, >>=
takes a function from Tree a
.
let rec index =
function
 Node(l, r) >
// WithCount (Tree a)
let li = index l
...
li >>= (fun ll > ???)
ll
is the naked value of the indexed left branch.
Here’s the trick to master >>=
. Focus on the types:
// WithCount Tree a Tree a > ...
li >>= (fun ll > ???)
Interpret it as follows:
WithCount
value.fun
you continue writing your code as WithCount
didn’t
exist. Your lambda operates on a naked value.This makes sense: >>=
is the onsteroids function application that
lets you think in terms of simple values, taking care of performing
all the logic related to the count
handling. Since the
count
handling logic is modeled with a WithCount
, it makes sense
that >>=
lets you ignore it.
In other words, >>=
unwraps any WithCount
value. Let me rephrase
the trick:
WithCount a
value, feed it to >>=
.a
only.Given this rule of thumb, implementing the Node
branch should be
trivial. You just have to continue unwrapping ri = index r
too:
let rec index =
function
 Node(l, r) >
let li = index l
let ri = index r
let buildNode' l r = pure' (buildNode l r)
li >>= (fun ll > ri >>= (fun rr > ???))
Cool. You have ll
and rr
to feed buildNode'
with:
let rec index =
function
 Node(l, r) >
let li = index l
let ri = index r
let buildNode' l r = pure' (buildNode l r)
li >>= (fun ll > ri >>= (fun rr > buildNode' ll rr))
Believe it or not, you are done.
For the Leaf branch, you need to perform 3 actions:
count
using getCount
.Leaf v, count
.count
with an incremented value, using putCount
.Both getCount
and putCount
operate in a WithCount
context:
// WithCount (Int, Int)
let getCount = WithCount(fun c > (c, c))
// Int > WithCount ((), Int)
let putCount c = WithCount(fun _ > ((), c))
That should not be a problem by now: you know the trick now, pass
WithCount
values to >>=
and you get the naked value.
So, let’s start from retrieving count
:
let rec index =
function
 Leaf (v: string) >
getCount
>>= (fun count > ...
You have both v
and count
. You can already build the return value:
let rec index =
function
 Leaf(v: string) >
getCount
>>= (fun count >
let leaf = Leaf(v, count)
Don’t return it just yet. You have to increment count
.
let rec index =
function
 Leaf(v: string) >
getCount
>>= (fun count >
let leaf = Leaf(v, count)
let newCount = count + 1
putCount newCount
...
Now, putCount
returns a WithCount ()
. Again, continue with >>=
and a lambda, and finally return the indexed leaf, inside a WithCount
:
let rec index =
function
 Leaf(v: string) >
getCount
>>= (fun count >
let leaf = Leaf(v, count)
let newCount = count + 1
putCount newCount
>>= (fun unit > pure' leaf))
Notice that as expected the unit
returned by putCount
is never
used. You can safely ignore replacing it with _
. Let’s put all
together:
let rec index =
function
 Leaf(v: string) >
getCount
>>= (fun count >
let leaf = Leaf(v, count)
putCount (count + 1)
>>= (fun _ > pure' leaf))
 Node(l, r) >
index l >>= (fun ll >
index r
>>= (fun rr >
pure' (buildNode ll rr)))
Run the test and see it pass.
The type WithCount
, together with >>=
and pure'
is what we call
a State Monad. In this implementation, it only accounts for an integer
count
, but nothing prevents you from making it more generic.
I know you are not excited. How could you be? That series of >>=
and
fun s >
makes head spin, don’t they? Yes, it’s true: it’s stateful
code with an imperative scent. See how:
putCount (count + 1)
seems to imperatively update a global variable. I’m sure you can follow the flow and understand it, and reading between the lines you can see how how it looks like imperative code. Yet, I bet you would call it all but fluent and readable.
If you are only partially satisfied with the result and you expected the State Monad to be more magic, you are not alone. The designers of Haskell also felt that expressions like the above could be improved with some little syntactic sugar.
So they invented the do notation. Which is what you are going to implement too in the next chapter, and which will make you see the true nature of LINQ.
Here’s what you got in Chapter 11:
let rec index =
function
 Leaf(v: string) >
getCount
>>= (fun count >
let leaf = Leaf(v, count)
putCount (count + 1)
>>= (fun _ > pure' leaf))
 Node(l, r) >
index l >>= (fun ll >
index r
>>= (fun rr >
pure' (buildNode ll rr)))
Remember again what >>=
does:
WithCount v
.v
.>>=
is that magic function that moves WithCount
out of sight,
while still accounting for it under the scenes.
In fact, the source of mess is the necessary presence of that lambda.
If you had a function foo
returning a WithCount String
:
// () > WithCount String
let foo () = WithCount "hello"
how beautiful would it be if you could replace:
foo() >>= fun (v > ...)
with just:
let! v = foo()
with a special let!
binding able to unwrap any WithCount
value,
and directly assigning the naked value "hello"
to v
?
If only you had that let!
binding, the whole index
function would
drammatically simplify. Instead of:
let rec index =
function
 Leaf(v: string) >
getCount
>>= (fun count >
let leaf = Leaf(v, count)
putCount (count + 1)
>>= (fun _ > pure' leaf))
 Node(l, r) >
index l >>= (fun ll >
index r
>>= (fun rr >
pure' (buildNode ll rr)))
you could operate the following transformations:
Original expression  Special form 

getCount >>= fun count > 
let! count = getCount 
putCount (count + 1) >>= fun _ > 
let! _ = putCount (count + 1) 
index l >>= fun ll > 
let! ll = index l 
index r >>= fun rr > 
let! rr = index r 
and the whole index
function would look like:
let rec index =
function
 Leaf(v: string) >
let! count = getCount
let leaf = Leaf(v, count)
let! _ = putCount (count + 1)
pure' leaf
 Node(l, r) >
let! ll = index l
let! rr = index r
pure' (buildNode ll rr)
Oh, this would be really a game changer, wouldn’t it? It would allow you to think imperatively, while being purely functional.
Of course, if that let!
binding existed, we would expect that under
the hood the F# compiler would automatically convert any:
let! vv = v
...
into:
v >>= (fun vv > ...)
Being a mechanical, deterministic transformation, that should not be an impossible dream.
It turns out that F# does support that syntax. All you have to do is
to teach it which >>=
and pure'
functions to use for those
tranformations. You need to create a custom type and to implement a
couple of methods:
type WithCountExpression() =
member this.Return v = failwith "Not yet implemented"
member this.Bind v f = failwith "Not yet implemented"
Return
is an alias name for pure'
. Bind
, as you already know, is
the name of >>=
. So, after all, you should already know how to
implement both:
type WithCountExpression() =
member this.Return(v) = pure' v
member this.Bind(v, f) = v >>= f
Now, just create an instance of it:
let withCount = WithCountExpression()
and, voilà!, you can use the new syntax:
let rec index =
function
 Leaf v >
withCount {
let! count = getCount
let leaf = Leaf (v, count)
let! _ = putCount (count + 1)
return leaf
}
 Node(l, r) >
withCount {
let! ll = index l
let! rr = index r
return buildNode ll rr
}
This is mostly what we initially desired, besides the extra
withCount { }
wrapping the whole epxression. The reason why this is
needed is because you can have multiple monads, and for each of them
let!
and return
must be transformed to a specific implementation
of >>=
and pure'
. This is a problem Haskell does not have: it
provides you with one single do
expression, covering all the
possible existing and future monads.
What you just implemented is called Computation
Expression. It is equivalent to (and
possibly more powerful than) the Haskell do notation,
which would allow writing index
as:
index (Leaf v) =
do {
count < getCount
let leaf = Leaf (v, count)
putCount (count + 1)
return leaf
}
index (Node l r) =
do {
ll < index l
rr < index r
return buildNode ll rr
}
You see the similarity, I hope!
Computation Expressions are super powerful, and they are pervasive in F#: they can handle async code, error management, optional values, sequence generations, logging etc. After all, they are syntactic sugar around arbitrary monads.
A little trick: when you want to ignore a value, you can always
replace let! _ = ...
with do! ...
. So, you can write index
as:
let rec index =
function
 Leaf v >
withCount {
let! count = getCount
let leaf = Leaf (v, count)
do! putCount (count + 1)
return leaf
}
 Node(l, r) >
withCount {
let! ll = index l
let! rr = index r
return buildNode ll rr
}
Naturally, it is again just syntactic sugar. Any:
do! foo()
...
is replaced with:
foo() >>= (fun _ > ...)
Let me stress that, although expressions like:
withCount {
do! putCount 42
do! putCount 0
do! putCount 99
return "Hello, world!"
}
look like a series of statements, under the hood each do!
like is
an expression *bound` to the next one: the whole is a unique
expression, in a chain of lambdas:
putCount 42 >>= (fun _ >
putCount 0 >>= (fun _ >
putCount 99 >>= (fun _ >
pure' "Hello, world!")))
Whatever you write inside a withCount
is a single, purely functional
expression.
In the index I claimed that this chapter would help you see LINQ for
what it is: a monadic engine. It you always saw LINQ as an embedded
SQL language, consider this implementation of index
, converted from
F# to C#:
private static WithCount<Tree<(A, int)>> IndexLINQ<A>(Tree<A> tree) =>
tree switch
{
Tree<A>.Leaf(var v) =>
from count in GetCount
from _ in PutCount(count + 1)
select BuildLeaf(v, count),
Tree<A>.Node(var l, var r) =>
from ll in Index(l)
from rr in Index(r)
select BuildNode(ll, rr)
};
It should not be hard to see these mappings:
F# syntax  C# LINQ syntax 

let! v = monadicFunction() 
from v in monadicFunction() 
return v 
select v 
Just like F#, in C# you can teach LINQ how to monadically handle
WithCount
values, instructing it which >>=
/ Bind
methods to
use. In C# the way to go is with Extension Methods:
internal static class WithCountExtensions
{
internal static WithCount<T> Pure<T>(T value) => new(count => (value, count));
internal static (T, int) Run<T>(WithCount<T> value, int count) => value.F(count);
internal static WithCount<TResult> Bind<T, TResult>(WithCount<T> a, Func<T, WithCount<TResult>> f) =>
new(count =>
{
var (va, ca) = Run(a, count);
var result = f(va);
return Run(result, ca);
});
internal static WithCount<TResult> SelectMany<T, TIntermediate, TResult>(
this WithCount<T> withCount,
Func<T, WithCount<TIntermediate>> intermediateSelector,
Func<T, TIntermediate, TResult> resultSelector) =>
new(count =>
{
var (value, intermediateCount) = withCount.F(count);
var intermediateWithCount = intermediateSelector(value);
var (intermediateValue, finalCount) = intermediateWithCount.F(intermediateCount);
return (resultSelector(value, intermediateValue), finalCount);
});
}
Yes, it’s way less readable than the equivalent F# version — now
you see why functional programmers prefer F# over C#, don’t you?.
You can find the complete C# implementation in
StateMonadTest.cs.
Anyway, here’s the take away: LINQ is much more than a tool for embedding SQL and manipulating lists. Just like the Haskell’s *do notation and F# Computation Expressions, LINQ is syntactic sugar for monads, any monad. LINQ is indeed a monad engine.
You can read more about it in Thinking Functionally: What is LINQ really?, from the languageext’s wiki.
You made it to the end! Congrats! If you found getting to the State Monad arduous, it is because it really was.
Here’s something that might catch you off guard: working with a
State Monad is really trivial.
I really think that this is a general trait of Functional Programming:
using functional programming concepts is orders of magnitude simpler
than reimplementing them from the scratch. What you have done, in
these 12 strenuous chapters, was to distill a State Monad out of thin
air, from the ground up, incrementally and taking many detours for
reasoning about any little nuance as you stumbled upon along the
journey.
In the next — much easier — chapters, I want to show you how easy and smooth working with a State Monad is, once it is implemented.
Stay tuned! I will publish them in the next days!
Interested in FP? Be the first to be notified when new introductory
articles on the topic are published.
In the previouls chapter you managed to write an algorithm able to traverse an arbitrary binary tree and to count the number of its leaves.
Let’s do something at first glance way more challenging: while
traversing the tree, the algorithm should generate a second tree with
the same shape, but with different, transformed components.
For example, let’s say that instead of having empty Leaves, each Leaf
holds a value of some type, such as a string:
Node
/ \
Leaf "one" Node
/ \
Leaf "two" Leaf "three"
While traversing this tree, the algorithm should generate a similarly shaped tree, whose Leaves contain the string length:
Node
/ \
Leaf 3 Node
/ \
Leaf 3 Leaf 5
You already know how to travese a tree. If you think how you counted the leaves, the code for traversing a tree and doing something else must have, more or less, the same structure. In pseudoF#:
let rec traverseTree =
function
 Leaf > doSomething
 Node(l, r) > recurse on l; recurse on r; combine the results
With an imperative language, without the constraint of immutability,
traversing a tree and changing the elements as they are visited is as
easy as pie. It is likely that, if you are not familiar with
Functional Programming, solving the same problem with the constraint
of immutability sounds a uphill battle.
Let’s overcome these fears.
First things first, we need a test:
let rec lengths =
function
 Leaf _ > failwith "Not yet implemented"
 Node(l, r) > failwith "Not yet implemented"
[<Fact>]
let ``calculate the leaves' content length`` () =
let treeOfWords = Node(Leaf "one", Node(Leaf "two", Leaf "three"))
let treeOfNumbers = Node(Leaf 3, Node(Leaf 3, Leaf 5))
let treeOfLengths = lengths treeOfWords
test <@ treeOfLengths = treeOfNumbers @>
You need to extend the Tree data structure so that its leaves can hold either integers and string values. Generic Types come to mind:
type Tree<'a> =
 Leaf of 'a
 Node of Tree<'a> * Tree<'a>
In Java and C# both Types and Type Parameters are capitalized. Without context, in C# it is not clear if:
List<T>
is a list generic on the type parameter T
or a list of T
, where
T
is a concrete type defined somewhere.
F# is kind enough to stick with a more explicit naming convention:
Element  Syntax  Example 

Types  Capitalized word  Tree 
Type parameters  Lower letter, prefixed by ' 
'a 
Haskell does the same, without the prefix.
Good. Let’s make the test happy.
Let’s start from the Leaf case.
let rec lengths =
function
 Leaf v > ???
If lengths
receives a Tree
, and this tree is a Leaf
containing a
string
, what should it return?
The rushed developer would imprudently answer: “the string length!”
let rec lengths =
function
 Leaf v > String.length v
To understand why this is wrong, let us write the lengths
’
signature. lengths
takes a tree of strings and returns a tree of
integers:
// Tree<string> > Tree<int>
let rec lengths =
function
 Leaf v > String.length v
(Yes, it’s horrible that primitive types such as string
and int
violate the naming convention and are not capitalized. So, from now on
I’m using the Haskell’s more strict convention).
It is apparent that the Leaf
case cannot return String.length v
,
because String.length v
is an int
, not a Tree<int>
.
Look again the sample reference:
Node Node
/ \ / \
Leaf "one" Node > Leaf 3 Node
/ \ / \
Leaf "two" Leaf "three" Leaf 3 Leaf 5
Leaf "one"
needs to be transformed into Leaf 3
, not into 3
.
It is more reasonable to implement the Leaf
branch as:
// Tree String > Tree Int
let rec lengths =
function
 Leaf v > Leaf (String.length v)
Notice that, just like for the leaves count problem, this is the base case of the recursion.
What to do when lengths
gets a Tree that is a Node
of a left and a
right branch? This is more puzzling.
If the Leaf branch was the base case, following the same pattern you can assume that in the Node branch there must be 2 recursive calls, plus a way to combine the results:
let rec lengths = function
 Leaf v > Leaf (String.length v)
 Node(l, r) > (lengths l) ??? (lengths r)
The problem is: how to combine the 2 values? What to replace ???
with?
It helps again to focus on the signature:
Tree String > Tree Int
and on the reference sample:
Node Node
/ \ / \
Leaf "one" Node > Leaf 3 Node
/ \ / \
Leaf "two" Leaf "three" Leaf 3 Leaf 5
You get a Node in, you return a Node out. The right implementation must be:
let rec lengths =
function
 Leaf v > Leaf(String.length v)
 Node(l, r) > Node(lengths l, lengths r)
Is the test green? Yes it is!
If the result reminds you of the leaves count case, it’s because it is almost the same:
let rec numberOfLeaves =
function
 Leaf > 1
 Node(l, r) > numberOfLeaves l + numberOfLeaves r
let rec lengths =
function
 Leaf v > Leaf(String.length v)
 Node(l, r) > Node(lengths l, lengths r)
You can stress on the similarity replacing the call to Node
with an
custom sumlike infix operator ^+
:
let (^+) l r = Node (l, r)
With it, you can build a Node with the very same syntax you used to sum 2 integers:
 Node(l, r) > lengths l ^+ lengths r
You can also stress that the Leaf branches are the base cases of recursion. You just need 2 helper functions.
let baseCase _ = 1
let baseCase' v = Leaf(String.length v)
Putting all together, you get:
let baseCase _ = 1
let baseCase' v = Leaf(String.length v)
let (^+) l r = Node (l, r)
let rec numberOfLeaves =
function
 Leaf v > baseCase v
 Node(l, r) > numberOfLeaves l + numberOfLeaves r
let rec lengths =
function
 Leaf v > baseCase' v
 Node(l, r) > lengths l ^+ lengths r
Now the 2 algorithms are really similar:
+
and ^+
).The fact that the shape of the two algorithms is the very same shoud not surprise: after all, both functions have to traverse the tree and, apparently, this shape captures the idea of traversing a tree.
The implementations are almost a copy/paste. And copy/pasting is the root of all evil. It would be cool to isolate the treetraversing code from the performed action.
This is what you are going to do in the next chapter.
In the last chapter we challenged ourselves to generalize the 2 almost identical functions. I have already spoiled it: doing so, you will invent Functors. Let’s go started.
Let’s consider again the original function:
// Tree String > Tree Int
let rec lengths tree =
match tree with
 Leaf v > Leaf(String.length v)
 Node(l, r) > Node(lengths l, lengths r)
This function contains both:
String.length
function for perfoming the domain logic.Instead of String.length
, imagine a function that parses strings to integers:
// String > Int
let parseWordToInt (word: string) : int =
match word with
 "one" > 1
 "two" > 2
 "three" > 3
 "four" > 4
...
and one that counts the vowels in a string:
// String > Int
let countVowels (input: string) : int =
// we don't even care about its implementation
Since both share with String.length
the same signature String >
Int
, you could easily use either in your algorithm:
// String > Int
let String.length (input: string) int = ...
// Tree String > Tree Int
let rec lengths tree =
match tree with
 Leaf v > Leaf(parseWordToInt v)
 Node(l, r) > Node(String.length l, String.length r)
and
// String > Int
let countVowels (input: string) : int = ...
// Tree String > Tree Int
let rec lengths tree =
match tree with
 Leaf v > Leaf(countVowels v)
 Node(l, r) > Node(algo l, algo r)
In fact, you can use any a > b
function, no matter the a
and b
types. It makes sense to generalize the function and abstract the
action away, passing it as a parameter f
. This would be akin to
implementing the Strategy Pattern.
You can introduce f
as a parameter either before or after tree
.
Putting f
after tree
would get to:
// Tree String > (String > Int) > Tree Int
let rec lengths tree f =
match tree with
 Leaf v > Leaf(f v)
 Node(l, r) > Node(lengths l, lengths r)
Placing f
before tree
would get to:
// (String > Int) > Tree String > Tree Int
let rec lengths f tree =
match tree with
 Leaf v > Leaf(f v)
 Node(l, r) > Node(lengths l, lengths r)
Notice that the implementation is perfectly the same.
You may not have realized it, but with the simple act of introducing
the f
parameter you made lengths
a highorder function, and you just invented Functors.
While the placement of a parameter might seem a superficial detail, it
actually reflects two fundamentally different mental models. Depending
if you have f
as the first or as the second parameter, the signature
reflects a completely different metaphor: either Functors as boxes or Functors are morphisms between categories.
This deserves some considerations, doesn’t it?
Let’s start from the version where the tree comes first:
// Tree String > (String > Int) > Tree Int
let rec lengths tree f =
match tree with
 Leaf v > Leaf(f v)
 Node(l, r) > Node(lengths l, lengths r)
Is the lengths
signature still correct? Is the name lengths
still reflecting the operation being performed?
Indeed, there is nothing in the implementation about calculating
lengths. And, to tell the whole truth, the function is not even about
strings anymore. It’s not hard to realize that the function is now
generic. If you ask the F# compiler which type it infers, it will
answer Tree a > (a > b) > Tree b
:
lengths
deserves a new name. To choose one, consider the mental
model you can use to interpret this signature:
Tree a
is a box containing a value of type a
.lengths
with such a box, plus a function f
from a
to b
, with the goal of applying f
to the box content.lengths
will do this for you,
giving you back a new box, containing a tranformed content of type
b
.Here’s a classic picture from Aditya Bhargava’s “Functors, Applicatives, And Monads In Pictures”:
It make sense to rename this transform
. LINQ calls it
Select
. Indeed, here’s the official signature of Select
in the .NET framework:
public static IEnumerable<TResult> Select<TSource, TResult>(
this IEnumerable<TSource> source, Func<TSource, TResult> selector)
It matches the model Box TSource > (TSource > TResult) > Box TResult
.
The Scala library Cats calls it map
. You can verify that it has the
same signature you obtained:
abstract def map[A, B](fa: F[A])(f: (A) => B): F[B]
Although this is a very popular implementation for Functors, I am not
particularly fond of it, and I think it’s based on a poor metaphor.
Let me show you a more powerful metaphor, enabled flipping f
and
tree
.
The signature (a > b) > Tree a > Tree b
is the one used by
Haskell (see fmap
on Hoogle):
// (a > b) > Tree a > Tree b
let rec map f tree =
match tree with
 Leaf v > Leaf(f v)
 Node(l, r) > Node(map f l, map f r)
The reason why this introduces a fundamentally different interpretation has to do with Currying and Partial Application. It may not be immediately apparent but, since functions associate on the right, the signature:
(a > b) > Tree a > Tree b
can be written as:
(a > b) > (Tree a > Tree b)
While:
// (a > b) > Tree a > Tree b
let rec map f tree = ...
can be interpreted as a function taking 2 parameters and returning a
Tree b
, the same function with the alternative, equivalent signature
// (a > b) > (Tree a > Tree b)
let rec map f =
fun tree > ...
can be interpreted as a highorder function taking 1 parameter only,
and returning a new function Tree a > Tree b
:
Notice how the following 2 forms are equivalent:
Uncurried  Curried 

let f a b = ... 
let f a = fun b > ... 
This is a general rule. Any F# function:
// a > b > c > d > e
let f a b c d e = ...
is completely equivalent to:
// a > (b > (c > (d > e)))
let f =
fun a >
(fun b >
(fun c >
(fun d >
(fun e > ...))))
This technique is called currying.
In reality, all F# (and Haskell) functions take 1 parameter only.
Multiparameter functions are an illusion, syntactic sugar based on
implicitely applied currying.
These different perspectives get to two completely different interpretations:
Form  Inputs  Output  Interpetation 

(a > b) > Tree a > Tree b 
A function:a > b plus a tree: Tree a 
A tree:Tree b 
Maps a function to a Tree 
(a > b) > (Tree a > Tree b) 
A function:a > b 
Another function:Tree a > Tree b 
Transforms / lifts a function 
Read again the curried form of our function:
// (a > b) > (Tree a > Tree b)
let rec map f =
fun tree >
match tree with
 Leaf v > Leaf(f v)
 Node(l, r) > Node(map f l, map f r)
You give map
a humble function f: a > b
, which can only
operate on a
values; map
transforms it into an onsteroids
function superF: Tree a > Tree b
.
To see this in practice, consider again the test method:
[<Fact>]
let ``calculate the leaves' content length, using map`` () =
let treeOfLengths = map String.length treeOfWords
test <@ treeOfLengths = treeOfNumbers @>
and focus on
map String.length treeOfWords
It’s feeding map
with 2 arguments. But we know that all functions
are 1parameter functions. What happens if you pass only 1 argument
— that is, if you partially apply it? In other words, what’s
the meaning of:
map String.length
Let’s see this in action:
let mapped = map String.length
let treeOfLengths = mapped treeOfWords
test <@ treeOfLengths = treeOfNumbers @>
If you ask F# to add type annotations on mapped
, it would write:
let mapped: Tree<string> > Tree<int> = map String.length
let treeOfLengths = mapped treeOfWords
test <@ treeOfLengths = treeOfNumbers @>
Read it like this: you feed map
with String.length
, a function
String > Int
which can only operate on strings; it gives you
back a superString.length
, which operates on trees of strings.
We can make this even more apparent aliasing map
with a custom
operator ^
:
let (^) = map
Guess if the following compiles:
let treeOfLengths = String.length treeOfWords
test <@ treeOfLengths = treeOfNumbers @>
Of course it does not! String.length
operates on strings, and
treeOfWords
is a Tree<string>
, not a string
. Let’s make it a
function onsteroids with our brand new ^
operator:
let treeOfLengths = String.length^ treeOfWords
test <@ treeOfLengths = treeOfNumbers @>
Wow! It works!
Can you see how this is based on the metaphor of lifting functions?
The idea is: you can think in terms of simple types, without worrying
about trees; you just write your ordinary functions operating on
ordinary types. Then, you lift your functions so they learn how to
operate on trees.
Let me use again this image by Bartosz Milewski, from the chapter Functors of his book Category Theory for Programmers:
to which I added a missing arrow. Here’s the metaphor:
C
, the lower world of ordinary functions and
values; and D
, the upper world of Trees.f
from the type a
to the type b
. In our case, String.length
.F f
that does the same of String.length
, but on Trees of strings
instead of just strings.map
/ ^
is that function that lifts whatever function f
,
operating on simple values, to the onsteroids function F f
,
operating on trees of simple values.This is the notion of Functors: something able to move objects and
functions from one world / category to another — possibly richer
— one.
This is not a series on Category Theory, so we will stop here on this
topic. It should suffice to interpret the result as follows:
map
, you capture the essence of
traversing a tree and applying a function to its content.String.length
, countVowels
, etc) from the treetraversing code.map
lifts ordinary functions
to treeoperating functions, without forcing you to reimplement the
traversing logic over and over.Cool. If you managed to read this far, take a break, reward yourself with a well deserved delicacy, and get ready to the next chapter. You are going to discover the limits of Functors.
Go to Chapter 4.
map
in Catsfmap
In the previouls chapter you
distilled map
, a function exhibiting 3 powerful features:
It sounds like a mighty function and in fact it is.
One may mistake, though, the possibility to pass an arbitrary
transformation function with the ability to perform any arbitrary
transformation. The two are not the same and, unfortunately, Functors
have limits to the trasformations they can produce.
Let’s put this statement to the test.
During its execution, map
traverses the tree. Very well: we want it
to keep a track of the order with which it visits the leaves. That
is, if it visits:
Leaf "one"
Leaf "two"
Leaf "three"
it should transform the tree:
Node
/ \
Leaf "one" Node
/ \
Leaf "two" Leaf "three"
into:
Node
/ \
Leaf ("one", 1) Node
/ \
Leaf ("two", 2) Leaf ("three", 3)
Let’s call this operation indexing a tree.
Here is the requirement:
[<Fact>]
let ``indexes a tree`` () =
let tree = Node(Leaf "one", Node(Leaf "two", Leaf "three"))
let indexed = map index tree
test <@ indexed = Node(Leaf ("one", 1), Node(Leaf ("two", 2), Leaf ("three", 3))) @>
If you come from an imperative language, you don’t have to think twice to find the solution:
let counter = 1
let index v =
let indexedLeaf = (v, counter)
counter = counter + 1
indexedLeaf
Now, F# is a grumpy functional zealot and will refuse to compile:
counter = counter + 1
“Variables must be immutable”, it will bemoan.
Not only does it demand you to explicitly declare counter
as
mutable:
let mutable counter = 1
but it also insists that you use a special syntax for mutating the value:
counter < counter + 1
To add insult to injury, Rider will underline all the 4 occurrences of
counter
to warn you with alarming voice “Mayday, mayday! A mutable
variable!”. They really go to great lenghts to make it hard to deviate
from purity, don’t they?
Anyway, once bow to F#’s will and run the test, you can finally
confirm that your impure index
function does work:
let mutable counter = 1
let impureIndex v =
let indexedLeaf = (v, counter)
counter < counter + 1
indexedLeaf
[<Fact>]
let ``indexes a tree`` () =
let tree = Node(Leaf "one", Node(Leaf "two", Leaf "three"))
let indexed = map impureIndex tree
test <@ indexed = Node(Leaf ("one", 1), Node(Leaf ("two", 2), Leaf ("three", 3))) @>
Now, give yourself 15 mins for a coding challenge. Try to get to the same green test, this time adding only one single extra constraint:
This means:
index
so that it is referential transparent.About the last comment, here’s a trick you can use: whatever function
you write, if it is pure, given the same argument it must always return
the same value. So, it must be always safe to invoke it twice.
So, write your test as follows:
[<Fact>]
let ``indexes a tree`` () =
let tree = Node(Leaf "one", Node(Leaf "two", Leaf "three"))
map index tree > ignore // intentionally invoked twice
let indexed = map index tree
test <@ indexed = Node(Leaf ("one", 1), Node(Leaf ("two", 2), Leaf ("three", 3))) @>
Another option is to define this function:
let invokedTwice f =
fun v >
f v > ignore
f v
and then, instead of:
let indexed = map index tree
to use:
let indexed = map (index > invokedTwice) tree
It will not take much to convince yourself that indexing a tree using a pure Functor is just not possible.
The problem is that, while traversing the tree, your algorithm must retain some form of memory, some kind of state.
So, you can draw an important conclusion:
Implementing stateful algorithms with pure functions is not possible.
Correct?
Nothing further from the truth.
You will prove that statement wrong in the very next chapter. Then you will build on top of that demonstration discovering Applicative Functors first, and finally the mighty State Monad.
Treat yourself with an icecream, and when you feel ready, jump to the chapter 5.
If you did your homework, in the chapter 4
you convinced yourself that map
:
let rec map f =
function
 Leaf v > Leaf(f v)
 Node(l, r) > Node(map f l, map f r)
is not as mighty as it needs to index a tree.
You need to create a more powerful function. Be ready to bet,
it will need to pattern match on leaves and nodes just like map
does.
Following this gut feeling, you can start from this scaffold:
let rec index =
function
 Leaf v > failwith "Not yet implemented"
 Node(l, r) > failwith "Not yet implemented"
[<Fact>]
let ``indexes a tree`` () =
let tree = Node(Leaf "one", Node(Leaf "two", Leaf "three"))
let indexed = index tree
test <@ indexed = Node(Leaf ("one", 1), Node(Leaf ("two", 2), Leaf ("three", 3))) @>
Let’s start from the leaf branch, again:
let rec index =
function
 Leaf v > failwith "Not yet implemented"
 Node(l, r) > failwith "Not yet implemented"
It might help to compare this with the wordlengthcalculation algorithm that you developed in Chapter 2:
let rec lengths =
function
 Leaf v > Leaf(String.length v)
 Node(l, r) > Node(lengths l, lengths r)
Let’s reason about the signature:
lengths :: Tree String > Tree (Int)
index :: Tree String > Tree (String * Int)
This should give you a hint. The leaf branch returns a leaf containing a tuple with the original value and the current counter:
let rec index =
function
 Leaf v > Leaf (v, count)
...
Cool. Now, you need to define count
.
How to define count
?
Now, reflect for a while, and ask yourself: where does count
come
from? Where to define it?
You have 2 options.
If there is a single takeaway you will ever remember from this series,
please, let it be this one. Big decisions often come from tiny, at
first glance harmless decisions. And I can tell you: this one is a
humongous decions. This is, indeed, the inflection point where your
code:
So, which options do you have? Try to find them out.
If you want to develop a functional attitude, I recommend you not to cheat, and to jump to the next chapter only when you have found out 2 possible options. They don’t need to be a complete solution. You just have to answer the question:
count
value come from?Have a long hot tea, or a whiskey and a cigar if you prefer, and take all the time you need. See you tomorrow in the chapter 6. Bye!
Welcome back! I hope your tea (or your whiskey and cigar) inspired you. We left each other in chapter 5 with an existential question:
Where does count
come from in this hypothetical, scaffold implementation?
let rec index =
function
 Leaf v > Leaf (v, count)
 Node(l, r) > failwith "Not yet implemented"
There are in fact 2 legit answers:
It is a global variable
let count = 1
let rec index =
function
 Leaf v > Leaf (v, count)
 Node(l, r) > failwith "Not yet implemented"
It is a function parameter:
let rec index count =
function
 Leaf v > Leaf (v, count)
 Node(l, r) > failwith "Not yet implemented"
This is a very strong design decision.
The implementation with a mutable variable is deliciously simple:
let mutable count = 1
let rec imperativeIndex =
function
 Leaf v >
let indexedLeaf = Leaf (v, count)
count < count + 1
indexedLeaf
 Node(l, r) > Node(imperativeIndex l, imperativeIndex r)
It really reminds the impure mapping function we wrote in chapter 3, it’s basically the same idea.
We could say a lot about this style, for example:
But this is the old litany every functional militant would repeat over and over. What I would like you to notice, instead, is:
Throughout this series, every time we managed to have a compiling
code, that was a reliable sign that the functionality was complete and
correct, and the green test was there to testify it. It’s not the case
here anymore. The very moment you resolve the dependency to
count
with an shared mutable variable, as far as the compiler is
concerned, the code is alredy complete and correct.
I like to interpret the apathy we are getting from the Type Sytem as if it is telling us:
“So you are not giving me any hints about the types at play. Fine, your loss, go ahead and do it your way”.
Is there a way to give the Type Sytem a hint about the types at play?
Yes, there is! And it is exactly the second option you found: passing
count
as a function parameter.
Here we go.
let rec index count =
function
 Leaf v > Leaf (v, count)
 Node(l, r) > failwith "Not yet implemented"
You might have missed it, but you just changed the index
signature,
that is, its type. Exactly what the Type Sytem was moaning about.
Original signature  New signature 

Tree a > Tree (a, Int) 
Tree a > Int > Tree (a, Int) 
Although the change is as simple as before (you just added a humble
count
), the Type Sytem will not let you down. On the contrary, it
immediately highlights all the lines where your code fails to compile.
Notice: a compilation error is not a harm. On the contrary: it’s a gift from Heaven, it’s a lighthouse to follow. Instead of being left to sink or swim, the Type Sytem is there to suggest you how to complete your implementation. Beautiful.
Before going ahead, notice that there were 3 positions where you could
have placed count
as a function parameter:
As the first index
parameter:
// Int > Tree a > Tree (a, Int)
let rec index count tree=
match tree with
 Leaf v > Leaf (v, count)
 Node(l, r) > failwith "Not yet implemented"
As the second index
parameter:
// Tree a > Int > Tree (a, Int)
let rec index tree count =
match tree with
 Leaf v > Leaf (v, count)
 Node(l, r) > failwith "Not yet implemented"
As the parameter of a nested lambda:
// Tree a > (Int > Tree (a, Int))
let rec index tree =
match tree with
 Leaf v > fun count > Leaf (v, count)
 Node(l, r) > failwith "Not yet implemented"
I would like to convince you that the 3rd option is the most convenient, because it better exhibits the mental metaphor of monads.
In Monads for the Rest of Us I postulate
that an intuitive interpretation of (some) monads is that they
encapsulate the act of postponing an execution of some (side) effects.
This viewpoint stands also in this case.
Focus on the 3rd option signature and on its leaf branch
implementation:
// Tree a > (Int > Tree (a, Int))
let rec index =
function
 Leaf v > fun count > Leaf (v, count)
...
I like to interpret it as it’s telling me:
Give me a Tree and I promise I will index it. I cannot index it just yet, because I have no idea which value
count
has. So, I give you back a function for you to feed with that value. As soon as you do that, I will complete my indexing task.
It’s really like this: index
is not returning an indexed leaf but a
function that eventually will create it. index
is blatantly
tricking you, procrastinating its duties. This is often the case with
monads.
Of course, now you cannot invoke index
anymore with:
[<Fact>]
let ``indexes a tree`` () =
let tree = Node(Leaf "one", Node(Leaf "two", Leaf "three"))
let indexed = index tree
test <@ indexed = Node(Leaf ("one", 1), Node(Leaf ("two", 2), Leaf ("three", 3))) @>
You need to pass it the first count
value:
let indexed = index tree 1
("three", 3))) @>
So far so good. Let’s see how to complete the node branch.
The node branch is in the same dilemma. It wants to complete its task
but it does not know the value of count
. So, it uses the same trick:
it returns a function that eventually will perform the indexing:
let rec index =
function
 Leaf v > fun count > Leaf (v, count)
 Node (l, r) >
fun count >
...
This is a very common trick in Functional Programming: if you need a value and it’s not there, you just create it from thin air, returning a function that requires it. It will be your caller’s duty to provide it. Doing so, you are propagating up to the call site, and through the Type Sytem, your need. The Type Sytem will make sure that this need is not ignored.
Cool. You have count
out of thin air. You can index the left branch,
then the right one. Then you can build a Node
with the resuls:
let rec index =
function
 Leaf v > fun count > Leaf (v, count)
 Node (l, r) >
fun count >
let li = index l count
let ri = index r count
Node (li, ri)
li
and ri
stand for left, indexed
and right, indexed
.
Wait a sec. There something not quite correct. The code compiles, but the test is red. For the first time, “if it compiles, it works” failed us.
Can you spot the problem? We are never incrementing the count
. This
is an issue at value level, not at type level, and the poor type
system cannot infer anything but at type level. (I argue: this is the
sign we should have improved the design using more fine tuned types,
such as Dependent Types. But this is a very advanced topic deserving
its own series).
Maybe we can increment count
right after having indexed the left
branch:
let rec index =
function
 Leaf v > fun count > Leaf (v, count)
 Node (l, r) >
fun count >
let li = index l count
let ri = index r (count + 1)
Node (li, ri)
But this is wrong. This assumes that the left branch only had 1 leaf.
We should increment count
with the exact number of leaves in the
left branch:
let rec index =
function
 Leaf v > fun count > Leaf (v, count)
 Node (l, r) >
fun count >
let li = index l count
let ri = index r (count + numberOfLeavesInLeftBranch)
Node (li, ri)
Shall we write a function to calculate it? Shall we add another recursive call?
There is a way simpler solution. In the mutable implementation we wrote before:
let mutable count = 1
let rec imperativeIndex =
function
 Leaf v >
let indexedLeaf = Leaf (v, count)
count < count + 1
indexedLeaf
 Node(l, r) > Node(imperativeIndex l, imperativeIndex r)
we rightly incremented count
in the leaf node. Let’s try to follow
the same path.
The question is: how to increment count
in the immutable version?
After all, it must be immutable…
Another useful perspective on returning a fun count >
is to view it
as a communication channel. it’s a way for the code to send
information back to its caller, back to the past. It says:
I don’t know who used to run before me, but it had to pass me the correct value of
count
You can use the same trick to send information forward to the future
code. You can send it the updated value of count
. Since you have to
return both the indexed tree and the updated value of count
, a
tuple comes to mind:
// Tree a > (Int > (Tree (a, Int), Int))
let rec index =
function
 Leaf v > fun count > (Leaf (v, count), count + 1)
 Node (l, r) >
fun count >
let li = index l count
let ri = index r count
Node (li, ri)
Notice how the leaf branch is returning 2 information:
Indexed tree  Future value for count 

Leaf (v, count) 
count +1 
Also notice that, again, the whole signature of index
, so its type!,
changed. And this immediately sets off alarms bells for the type
system. That, ideed, signals that the node branch fails to compile. Of
course!
// li :: Tree (a, Int), Int
let li = index l count
li
now is not an indexed tree anymore. It’s an indexed tree plus
the updated value for count
, calculated by traversing the left
branch. Useful. Let’s decompose it:
// Tree a > (Int > (Tree (a, Int), Int))
let rec index =
function
 Leaf v > fun count > (Leaf (v, count), count + 1)
 Node (l, r) >
fun count >
let li, lc = index l count
let ri, rc = index r count
Node (li, ri)
lc
stands for left count
; rc
for right count
.
Still not compiling. Good! There are 2 problems:
count
?// Tree a > (Int > (Tree (a, Int), Int))
let rec index =
function
 Leaf v > fun count > (Leaf (v, count), count + 1)
 Node (l, r) >
fun count >
let li, lc = index l count
let ri, rc = index r lc
Node (li, ri)
As for 1, this is very simple. After indexing the left branch, do we
have the updated value of count
? Yes we have, it’s lc
, the left
count:
As for 2, the Type Sytem complains that we should return a tuple, not
an indexed tree only. Sure, let’s return the count too. Which is the
most updated value? rc
, of course, the value the indexing of the
right branch conveniently sent to its future clients:
// Tree a > (Int > (Tree (a, Int), Int))
let rec index =
function
 Leaf v > fun count > (Leaf (v, count), count + 1)
 Node (l, r) >
fun count >
let li, lc = index l count
let ri, rc = index r lc
Node (li, ri), rc
There is still a last compilation error (thank you, Type System, for being so vigilant and meticulous):
[<Fact>]
let ``indexes a tree`` () =
let tree = Node(Leaf "one", Node(Leaf "two", Leaf "three"))
let indexed = index tree 1
test <@ indexed = Node(Leaf ("one", 1), Node(Leaf ("two", 2), Leaf ("three", 3))) @>
Yes! index tree 1
returns the indexed tree and a new counter,
which we can safely ignore:
[<Fact>]
let ``indexes a tree`` () =
let tree = Node(Leaf "one", Node(Leaf "two", Leaf "three"))
let indexed, _ = index tree 1
test <@ indexed = Node(Leaf ("one", 1), Node(Leaf ("two", 2), Leaf ("three", 3))) @>
It compiles. It’s green. We did it! Look how beautiful: you did a stateful algorithm without any single variable.
And it’s inherently threadsafe. It was guided by the type system.
And best of all, it’s so readable!
You are right: the result is horrible. It’s a contrived, convoluted gimmick.
Let me enumerate its ugliest parts:
Yes, there is! And it can be found as soon as you identify the root cause:
Sometimes coding is so predictable, isn’t it? It’s always the same old problems. With approving smiles and nods, the Venerable Sages observe us contentedly, implying: “it’s all about the Single Responsibility, the Open Closed, the Dependency Inversion Principles. It’s always a matter of Low Coupling and High Cohesion”.
So, you know how to get out of this mess: you have to separate the
domain logic from the statehandling logic.
Once you separate them, what you will end up with is:
Here’s a spoiler alert:
let rec index =
function
 Leaf v >
withCount {
let! count = getCount
do! setCount (count + 1)
return Leaf(v, count)
}
 Node(l, r) >
withCount {
let! li = index l
let! ri = index r
return Node(li, ri)
}
{ }
: besides some weird !
here and
there, this is the old imperative code that you find easy to write.withCount
expression: treat is as a new F# keyword that
tells the compiler to treat the enclosed code as stateful.That withCount
is the State Monad (hidden behind a Computation
Expression).
Notice that, although the code seems imperative, it is purely
functional. Even if:
let! li = index l
let! ri = index r
seem 2 sequential statements, they are in fact 2 functions bound
together with the bind
operator. Puzzling, isn’t it? I’m sure you
understand that, to fully get there, we still have to walk a bit. I
promise that it will be an interesting journey!
You need a bit of energy. So stretch your fingers, take a little rest, have a sorbet and then we will get going!
See you in Chapter 7.
Interested in FP? Be the first to be notified when new introductory
articles on the topic are published.
Enjoyed the sorbet? Gather your strengths, you will need them! These chapters will be a bit more challenging than the ones in Part I but, hopefully, also more rewarding.
So, we closed chapter 6 with this code:
// Tree a > (Int > (Tree (a, Int), Int))
let rec index =
function
 Leaf v > fun count > (Leaf (v, count), count + 1)
 Node (l, r) >
fun count >
let li, lc = index l count
let ri, rc = index r lc
Node (li, ri), rc
[<Fact>]
let ``indexes a tree`` () =
let tree = Node(Leaf "one", Node(Leaf "two", Leaf "three"))
let indexed, _ = index tree 1
test <@ indexed = Node(Leaf ("one", 1), Node(Leaf ("two", 2), Leaf ("three", 3))) @>
and we commented that it is a pity that the code for handling the
state (the value of count
) is interleaved with the domain logic
code. It is also a pity that the function signature —its type
— got so complicated.
Indeed, types are exactly where the key to the next step lies. You
surely remember when we enumerated the possible placements for the
count
parameter:
Position  Signature 

As the first index parameter 
let rec index count tree = ... 
As the second index parameter 
let rec index tree count = ... 
As the parameter of a nested lambda  let rec index tree = match tree with  Leaf v > fun count > .... 
and you remember that we went with the 3rd option. You might have already noticed that the last 2 are equivalent. Compare their signatures:
Position  Signature 

As the second index parameter 
Tree a > Int > (Tree (a, Int), Int) 
As the parameter of a nested lambda  Tree a > (Int > (Tree (a, Int), Int)) 
The latter has a couple of extra parenthesis, which are anyway
implicit in the former.
We preferred the latter because it makes it clear that the
function index
is returning a kind of a promise: it does not
directly return an indexed tree Tree (a, Int)
; instead, it returns a
function that, once fed with the value of count
, will carry its job
out. Not only: it will return an indexed tree plus a new count
value, all in a tuple.
Wow. That’s a mouthful. Even attempting to explain the signature is utterly exhausting. It is definitely worth to simplify it.
As it often happens in Functional Programming, the first step to elaborating an idea — to simplify it — is to give it a name. Giving an idea a name really means to define a type to represent it. The more you will apply Functional Programming, the more you will find yourself modeling your applications through types.
There are 2 ways I can suggest you to tackle this step.
They are 2 sides of the same coin.
Observe again index
:
let rec index =
function
 Leaf v > fun count > (Leaf (v, count), count + 1)
 Node (l, r) >
fun count >
let li, lc = index l count
let ri, rc = index r lc
Node (li, ri), rc
and notice how both the branches return a naked fun count >
...
. Let’s pack it inside a container, which we will call
WithCount
:
let rec index =
function
 Leaf v > WithCount (fun count > (Leaf (v, count), count + 1))
 Node (l, r) >
WithCount (
fun count >
let li, lc = index l count
let ri, rc = index r lc
Node (li, ri), rc)
Spoiler alert: WithCount
is the type around which you will develop
the State Monad. Keep an eye on it.
WithCount
does nothing but holding that convoluted function. In a
sense, it decorates it, it encapsulates the function and hides its
complexity. More importantly, having a name, it gives us the chance to
define dedicated functions to operate on it. Which functions? Well,
first of all, the ones we need to fix the compilation errors. There
are severals, and they revolve around 2 problems:
WithCount
is not even defined.index
does not return a function anymore: its returned value
cannot be directly executed.Let’s proceed in order.
WithCount
can be defined as:
type WithCount = WithCount of ???
Remember: the WithCount
on the left is the type. The WithCount
on
the right is not: it is the data constructor that can be used to build
an instance of WithCount
. Think of it as the C# class constructor.
What to replace ???
with? Let’s be lazy and let’s ask F# itself. If
you extract the argument of WithCount
to a variable, you can use the
F# type inference to ask the F# compiler its opinion:
let rec index =
function
 Leaf v >
let f: int > Tree<'a * int> * int = (fun count > (Leaf (v, count), count + 1))
WithCount f
...
So, F# claims that the function encapsulated by WithCount
has the type:
Int > (Tree (a, Int>), Int)
This matches our experience:
Int 
Tree (a, Int>) 
Int 

The previous value for count 
The indexed tree  The next value for count 
In fact, we could be way more generic. For the time being, let’s
settle for this little generalization, using v
instead of Tree (a,
Int)
:
type WithCount<'v> = WithCount of (int > 'v * int)
This makes WithCount
not specific to trees. Afterall, the logic for
traversing trees is already implemented in index
: it does not need
to affect WithCount
too. Indeed, it might not be immediately
evident, but what this WithCount
definition does, it to isolate the
pure, domain logic from the counthandling logic. We will discuss this
more thoroughly in the next chapters.
WithCount
Now for the other compilation issues. Your code is full of invocations
of that function that now fail to even compile, because the function
is hidden behind a WithCount
type. Take the test, for example:
[<Fact>]
let ``indexes a tree`` () =
let tree = Node(Leaf "one", Node(Leaf "two", Leaf "three"))
let indexed, _ = index tree 1
test <@ indexed = Node(Leaf ("one", 1), Node(Leaf ("two", 2), Leaf ("three", 3))) @>
The:
index tree 1
fails to compile. You could read it as:
(index tree) 1
Before you introduced WithCount
, index tree
used to return a
function and was equivalent to:
// f :: Int > (Tree (String, Int), Int)
let f = index tree // invoking index
f 1 // invoking the returned function
f
was a function ready to be invoked. After the last change, what
you get is instead:
// WithCount Tree (string, int)
let withCount = index tree // invoking index
withCount 1 // this fails to compile
Not an invocable function anymore.
By the way: notice the simplification you already gained. What you get
back from invoking index
is an indexed tree, Tree (string, int)
,
surrounded by a WithCount
. In this signature, there is no mention at
all to the counthandling logic. As I commented before, WithCount
lets you
liberate your domain logic from the state handling.
Let’s fix the compilation errors. F#’s function application is not
smart enough to pass an argument to a function when it is inside a
WithCount
. You need a special version of function application. Let’s
call it run
:
let run (withCount: WithCount) count =
let f = <get the function held by withCount>
f count
Getting the function held by WithCount
is idiomatically done in F#
with Pattern Matching. You remember that in chapter
1 we mentioned that an instance
remembers which constructor was used to create it, and that you can
deconstruct the instance getting to the original arguments. It’s way
easier done than said:
let run (WithCount f) count = f count
Cool. run
is a superfunction application that works for functions
held by a WithCount
shell. If you have read Monads for the Rest of
Us you remember that I insist that monads
are not a thing. In a sense, they don’t exist; monadic functions
do, and the key to understanding monads is to implement versions of
function application and function composition able to work with this
extended notion of functions. Here you are doing something very
similar: it is like you invented a novel notion of function. index
is a function that returns an indexed tree, plus an indication of
an extraeffect: depending on an input count
, and returning back an
updated version of count
itself. In other words, index
is a
function that, besides doing its pure work, also lives in a context
where some state must be considered.
Instead of functions:
f :: a > b
you are now dealing with functions:
f :: a > WithCount b
which are a bit harder to concatenate, unless you extend some F#’s native functionalities.
Back to fixing the compilation errors using you novel run
function.
Here’s the working result:
type WithCount<'v> = WithCount of (int > 'v * int)
let run (WithCount f) count = f count
let rec index =
function
 Leaf v >
WithCount (fun count > (Leaf (v, count), count + 1))
 Node (l, r) >
WithCount (
fun count >
let li, lc = run (index l) count
let ri, rc = run (index r) lc
Node (li, ri), rc)
[<Fact>]
let ``indexes a tree`` () =
let withCount: WithCount<string> = index tree
let indexed, _ = run withCount 1
test <@ indexed = Node(Leaf ("one", 1), Node(Leaf ("two", 2), Leaf ("three", 3))) @>
So far, you got a bit on improvement on the signature, but the
implementation code is still convoluted, and domain logic and
counthandling logic are still interwoven.
It’s time to sort the tangle out, and to invent the Applicative
Functor. Feel free to have a coffee! See you in a minute in Chapter
8.