Yes, I'm writing about *monads* but fear not; I won't be delving into the depths of category theory. Instead this post shall attempt to remain practical, showing that in practice monads don't have to complex and difficult to understand and actually can be derived simply through refactoring—they're just another abstraction.

Right, let's get started. Imagine that we're building some kind of project component, for manipulating project files which contain lists of files from various sub-directories. Something there could be in an IDE. One might find the following interfaces:

```
type ProjectFile(path:string) = ...
module Project
find :: string -> string option
load :: string -> ProjectFile option
```

There's a `ProjectFile`

for encapsulating properties and methods of project files and two functions in the `Project`

module: `Project.find`

to recursively ascend from the current directory until it finds a file with the right extension and `Project.load`

to parse and load a project file, given its path. Creating and using a project would thus look something like the following:

```
let doSomething path =
let projectPath = Project.find path
match projectPath with
| None -> None
| Some p ->
let projectFile = Project.load p
match projectFile with
| None -> None
| Some f -> f.listFiles()
```

Eeek! That's not very clean, is it? The intuitive refactoring would be to extract the method out like so:

```
let loadProject path =
match Project.find path with
| None -> None
| Some p -> Project.load p
let doSomething path =
match loadProject path with
| None -> None
| Some prj -> prj.listFiles()
```

This isn't awful but it would have to be redefined for any other cases of nested matches too, which isn't perfect either. The repeated `| None -> None`

matches don't look very nice either, it would be ideal if they could just be ignored. What would be ideal is a function that ignores `None`

and passes through any values that do exist; something like this:

```
let ifSome opt f =
match opt with | Some s -> f s | _ -> None
let doSomething path =
ifSome (Project.find path) (fun p ->
ifSome (Project.load p) (fun prj ->
prj.listFiles()))
```

Well, that's gotten rid of those matches at least but it's not exactly elegant. Let's swap out that prefix-positioned function call for an infix operator:

```
let (>>=) opt f =
match opt with | Some s -> f s | _ -> None
let doSomething path =
Project.find path >>= Project.load >>= (fun prj ->
prj.listFiles())
```

Eureka! Now that's much better. I'm sure you're looking for where monads start coming in to this? Well, I just used them. Option *is* a monad and `>>=`

is one of the two monadic operators, called *bind*. The signature of which, for any monad type `m`

is `m a -> (a -> m b) -> m b`

The other operator is *return* which takes an ordinary value and wraps that value in the monad (signature `a -> m a`

), for `Option`

this is, of course, just the `Some`

constructor. These two operators can be defined for any monad and used in very similar ways thus working with them can translate to *any* domain or data structure. So, you see, dear reader, monads don't have to be hard; bind especially can be really useful in removing nested stuctures or calls.

There are actually a few implementations of these operations in the core library, the `async`

and `seq`

computation expression builders define a number of methods including `Bind`

and `Return`

. In fact computation expressions are essentially syntactic sugar on top of some sort of monads. You can see the operators that are used to build computation expressions and a little more information on how they work here. Although, as demonstrated above, they don't really produce very clean code when used in a prefix position. Aliasing them to operators or just using the computation expressions is likely a good idea in most cases.