Your initial understanding of Monad concept, after reading a couple of tutorials (many of them are available in the web), might not be very good and that's because of The Curse of the Monad:

In addition to it begin useful, it is also cursed and the curse of the monad is that once you get the epiphany, once you understand - "oh that's what it is" - you lose the ability to explain it to anybody.Although the curse might be real, I'm writing here yet another monad tutorial because, what I believe, the best way to understand monad is to write tutorial about it :-)

-- Douglas Crockford

## Monad - introduction

The concept originates from category theory. In functional programming:

**monad as generic concept describes how to build chains/pipelines of operations while concrete monad type defines what it actually means to chain/compose operations**.

Thus we can extract two concepts here:

**Monad**- provides the abstract interface for monadic operations**Monadic type**- a particular class that implements monadic operations

Generally speaking monads are used to make things composable. Many different things (such as computations or data containers) can be expressed as monadic types. Because of that universal nature of monads, many programming functional languages provide special syntax (Haskell, Scala) or functions (Clojure) to make composition of monadic types easy to write in the code.

Before we get to monadic types, we will first see how function composition and application work and then we will see how to use those concepts to build composable structures (monadic types). We will use Haskell notation to define functions as it is very concise.

### Function application

Lets define function

`f`

that returns its argument multiplied by 2:f :: Int -> Int // f takes int, returns int f = \x -> 2 * x // f is constructed using lambda expression (anonymous function), thus \x -> ...Then:

f 2 --> has value 4Now, calling a function with an argument can be generalized as a new function that calls given function (passed as first argument) with given argument (passed as second argument), or in other words, applies given function to given argument. This new function can be expressed as function application operator (

`$`

- in Haskell) :($) :: (a -> b) -> (a -> b) // $ takes function, returns function, this is the same as ((a -> b), a) -> b, instead of passing all arguments at once, we can pass first argument to function, receive partially applied function, and pass second argument to it. This is called currying (http://en.wikipedia.org/wiki/Currying). f $ 2 --> has value 4 // $ is an infix operator, so it must be put between its arguments ($) f 2 --> has value 4 // Putting parenthesis around an infix operator converts it into a prefix operatorIf we define

*reverse apply*operator:

`(>$>) :: a -> (a -> b) -> b`

we can express function application as following:

`2 >$> f`

Notice that unix shell's pipe (|) operator works this way - you produce some data and then apply a program to it to transform it in some way. The arrows in

`>$>`

indicate the direction of data flow (result from previous operation is forwarded to next operation).### Function composition

Let's say we have two functions

`f`

and `g`

and a value `x`

with the following types:x :: a f :: a -> b g :: b -> cfor some types a, b, and c.

We can create new function

`h :: a -> c`

that combines f and g.`h = g . f = \x -> g (f x)`

So, composing two functions produces a new function that, when called with a parameter

`x`

is the equivalent of calling `f`

with the parameter `x`

and then calling the `g`

with that result.Note that this will only work if the types of

`f`

and `g`

are compatible, i.e. if the type of the result of `f`

is also the type of the input of `g`

.Example usage:

f = \x -> x + 2 g = \x -> x * 3 h = g . f h 2 --> has value 12

### Composition in terms of application

We can easily discovery that

`h`

can be defined as **application of**.

`g`

to result of `f`

To better visualize data flow we need another operator that is reversed version of function composition operator

`.`

:`h = f >.> g`

So, the key here is to understand that in order to combine two functions we need to provide a new function that calls second function with result of first function.

As it will turn up,

`>.>`

function is the core ingredient of monadic type.## Monadic type

So far we have only considered functions as units of composition. But what we want to achieve is composable structure / class.

Lets introduce classes to our functions and start thinking how we can compose them applying the rules of function composition.

To implement examples, we will use

**Scala**- hybrid functional-OO language.

Lets introduce abstract generic class

`Monad[A]`

and simple class `IntWrapper`

that will extend `Monad`

and wrap integer value: trait Monad[A] {} case class IntWrapper(value: Int) extends Monad[Int] {}

Now, instead of function

`Int -> Int`

lets define function `Int -> Monad[Int]`

f :: Int -> Monad[Int] f = \x -> IntWrapper(x + 2) g :: Int -> Monad[Int] g = \x -> IntWrapper(x * 3)

So, how we can compose those functions?

`h = f >.> g // won't work`

We can't use

`>.>`

operator because the types do not match. It is not possible to apply `Int -> Monad[Int]`

to `Monad[Int]`

. We need `Int`

, not `Monad[Int]`

The solution would be to create a different composition operator/function that would extract

`Int`

from `Monad[Int]`

before performing application but that would require `Monad`

to provide some kind of extract method. That doesn't sound like a good idea (and in fact would break the whole idea of Monad).As a great OO developer you have probably already come up with the solution.

`Monad`

itself should provide this function as a method! That way, the class itself will define what does it mean to compose it with another monad of the same type! This method is one of the two fundamental monadic operations, it is usually called **bind**, in Haskell it is

**>>=**, in Scala it is

**flatMap**. Lets stay with a Haskell notation for a moment.

Notice that

`>>=`

is very similar to `>.>`

(regular function application operator), except that it works for "monadic functions" - functions returning monadic type.So now, assuming our

`IntWrapper`

implements `>>=`

we can define `h`

function that combines `f`

and `g`

:`h = f >>= g`

or, keeping in mind that

`h`

must be called with a parameter that it will be passed to `f`

, we can define `h`

as following:`h = \x -> f x >>= g`

Conceptually

`>>=`

is still a function application operator (takes a result of one function and applies another function to it):(Int -> Monad[Int]) >>= (Int -> Monad[Int])but in fact

`>>=`

is a method of monadic type with the following signature:>>= :: (Int -> Monad[Int]) -> Monad[Int]The method

`>>=`

must apply given function `Int -> Monad[Int]`

to some `Int`

(it must call given function with some argument `Int`

), but what exactly will be the value of the argument is decided by the monadic type itself (our `IntWrapper`

may decide just to pass a value member to the function).

**With the implementation of**

`>>=`

monadic type describes the meaning of composition. It defines what does it mean to compose it with another monad of the same typeWe can also say, that by implementing

`>>=`

monadic type defines how to apply given function to itself.Lets see how we can compose

`IntWrapper`

s, assuming `IntWrapper`

defines composition as just passing an `Int`

value forward:case class IntWrapper(value: Int) extends Monad[Int] { override def >>=(f: Int => Monad[Int]): Monad[Int] = { f(value) } } def h(a: Int) = { IntWrapper(a + 2) >>= (b => IntWrapper(b * 3)) } h(2) // <-- has value IntWrapper(12)

OK, this is not very usable application of monad as nothing is happening during composition (in the background).

In next, still simple (or even stupid simple, but more funny) example we will define one more monadic operation that will let us take use of syntactic sugar provided by Scala to compose monads more easily.

## Uncertainty principle

In quantum mechanics, there is a rule saying that there are pairs of physical properties of particle (observables) known as complementary variables, that can not be measured simultaneously with arbitrarily precision. Complementary variables are for example position and momentum (of a particle).

We can encapsulate uncertainty of measurement inside

`Observable`

monadic type by implementing `>>=`

appropriately ensuring that any calculation that takes any number of `Observable`

s can only be performed as monadic operation, meaning `Observable`

s must be composed in order to unveil their values that are required to calculate the result (another `Observable`

). Putting it differently,

`Observable`

will not allow accessing its value directly, but only when used in special context (we can name it as laboratory or measurement) which can be easily created using Scala's *for comprehension*- syntax to simplify monadic composition.

The essential part will be of course

`>>=`

method of `Observable`

class. What we can do is to create a new value as a sum of internal (real) value property of Observable and some random value (between 0 and 1) whenever composition occurs (to simulate the distortion of one of the two observables that are measured) and forward this new value in composition chain: case class Observable[A <: Number](value: A) extends Monad[Number] { // remember, flatMap is what Scala expects as monadic apply (aka bind) operator, it is >>= in Haskell override def flatMap[B](f: Number => Monad[B]): Monad[B] = { f(Math.random() + value.doubleValue()) }Now we can define a method that performs measurement and calculates some value in a result:

def combinationOfPositionAndMomentum = for /*start measuring*/ { position <- Observable(4) momentum <- Observable(6) } yield /*calculate result*/ { BigDecimal.valueOf( if (position.doubleValue() > 4.5) { momentum.doubleValue() + position.doubleValue() } else { momentum.doubleValue() - position.doubleValue() } ) } combinationOfPositionAndMomentum // <-- has value Observable(10.95) combinationOfPositionAndMomentum // <-- has value Observable(1.83)After executing two experiments and checking the results (10.95 and 1.83) we can conclude that uncertainty principle is a fact ;)

Well, what we can say for sure is that

`flatMap`

method has been called what indicates that composition took place.As you can see there is no invocation of

`flatMap`

method on first `Observable`

in the code. This method call is generated automatically by the compiler. The function which is passed to `flatMap`

method of first `Observable`

is created by the compiler and basically what it does it takes the expression inside `yield`

block and creates monadic type from it (wraps it into monadic type). Complete code that is generated looks like this:Observable(4) flatMap (position => Observable(6).map( momentum => //content of yield (result calculation) )As you can see monadic type

`M[A]`

is expected to implement method `map :: A -> B -> M[B]`

(second monadic operation next to `bind`

) that is able to create `M[B]`

using given function `A -> B`

, assuming monadic type provides "constructor" applicable to `B`

. In our example:

- type of input observables is
`Observable[Integer]`

- type of expression inside yield block is
`BigDecimal`

- type of the whole expression (
`for`

in Scala is an expression, it returns value) is`Observable[BigDecimal]`

`map`

on the last observable in a block is necessary to do the "conversion" from `BigDecimal`

to `Observable[BigDecimal]`

.Now, lets do the final experiment:

val singleMeasurement = for { v1 <- Observable(4) } yield { v1 + 4 } singleMeasurement // <--- has value Observable(8)Obviously this time

`flatMap`

was not invoked, just `map`

. So, as expected, when we do some calculations with only one `Observable`

, distortion of measurement does not occur.You can check the complete source code here.

Lets see now some examples of monads that are available in Scala.

## Some well known monads

### Option

`Option[A]`

- represents a value that is either a single value of type A, or no value at all. **This is a hammer for nulls and helps avoiding**. When dealing with several optional values (instances of

*NullPointerException*`Option`

), we avoid checking for null (using nested if statements) by simply using monadic composition.```
val map: Map = ...
for {
value1 <- map.get("key1")
value2 <- map.get("key2")
} yield {
value1 + value2
}
// result is Option[Nothing] if either value1 or value2 is null
// As soon as null is detected in the chain of function calls, Option[Nothing] is propagated to the end of the chain.
```

### List

`List[A]`

- you might be surprised, but list is a monad too. Thats why you can compose lists easily:```
for {
v1 <- List(1, 3, 5)
v2 <- List("2", "4", "6")
if v1 < v2.toInt
} yield {
v1 * 10 + v2.toInt
}
// result is List(12, 14, 16, 34, 36, 56)
```

### Future

`Future[A]`

- represents a value of type A being a result (initially unknown) of some operation. Helps chaining operations that are executed asynchronously. See: Future is a Monaddef slowCalcFuture: Future[Int] = ... val future1 = slowCalcFuture val future2 = slowCalcFuture def combined: Future[Int] = for { r1 <- future1 r2 <- future2 } yield r1 + r2

### Either (from Scala core) or Validation (from scalaz)

`Either[A, B]`

- represents value that is either A or B (typically error or result of computation). Helps hiding the boilerplate "try/catch logic".`Validation`

(from scalaz) allows to accumulate errors (`Validation`

is actually not a monad but applicative functor).def costToEnter(p : Person) : Validation[String, Double] = { for { a <- checkAge(p) b <- checkClothes(a) c <- checkSobriety(b) } yield (if (c.gender == Gender.Female) 0D else 5D) } //example source code found here: https://gist.github.com/oxbowlakes/970717

### Other examples

- Towards an immutable domain model - monads - interesting way of handling validation and operation chaining in event sourced aggregates using monadic type (Behavior)

## Composing monads

It may sound strange but monads generally do not compose with each other. But of course, there is always a workaround: monad transformers. We will not go so far.. I will end up here.

Thanks for the tutorial. It's the best I have found. I completely skipped the Uncertainty principle. It was too far fetched for me. What do you mean by "monads generally do not compose with each other" when the title is "Monads - function composition on steroids". It kind of refutes the title.

ReplyDeleteThanks Yirie for your feedback. Monads do not compose because you can not compose Monad[A] with Monad[B]. As mentioned in the article a workaround is to use Monad Transformers (http://book.realworldhaskell.org/read/monad-transformers.html).

ReplyDeleteHow do I re-implement the Observable example using Scala Numeric typeclass of Java's Number?

ReplyDelete