Monads and Monoids
Intro
In the context of functional programming what are Monads Monoids and functors and why are they the basic building blocks of functional design. There is also some example code that was written in a Scala worksheet so you can cut and paste and play with it.
Monoid
A Monoid is a design pattern expressing function composition of items in a set. A monoid is a function that takes two arguments and returns an argument of that type and it supports both the identity property and the Associativity property. It is a fairly simple function definition. If you look at the trait that expresses it you can see what I mean.
trait Monoid[A] {
def identity : A
def associativity (x: A, y: A ) : A
}
A monoid function must always support the Identity property and the associativity property. As an example look at Integers
Integers
Associativity = a+(b+c) == (a+b)+c
Identity = 0+n == n+0 == n
Now take a look at String concatenation
String Concatenation
Associativity = a+(b+c) == (a+b)+c
Identity = s+"" == s and ""+s == s
Functor
A functor comes from category theory in mathematics where a function maps between two categories. In Scala this is a function that maps A => B. The trait is as follows:
trait Functor[A] {
def map[B](f: A => B ) : Functor[B]
}
At this point you should be thinking this is the map function that is so widely used in Scala.
Monads
A monad is a Functor that also supports flatMap which is just a map but that allows mapping to another monad. Lets look at the trait that expresses this.
trait Monad[A] {
def flatMap[B](f: A => Monad[B]) : Monad[B]
def identity[A](f: A): Monad[A]
def map[B](f: A => B ) : Monad[B]
}
You will also see the Identity function here because if you think about what map and flatMap does you need to know who you are so you can apply recursion.
Examples
Now we have the basic definitions out the way let me explain how we can use these concepts.
val x,y = (0 to 12 by 2 ).toList
> x : List[Int] = List(0, 2, 4, 6, 8, 10, 12)
> y : List[Int] = List(0, 2, 4, 6, 8, 10, 12)
val xy = x flatMap { xi => y map { yi => yi * xi }}
> xy : List[Int] = List(0, 0, 0, 0, 0, 0, 0,
0, 4, 8, 12, 16, 20, 24,
0, 8, 16, 24, 32, 40, 48,
0, 12, 24, 36, 48, 60, 72,
0, 16, 32, 48, 64, 80, 96,
0, 20, 40, 60, 80, 100, 120,
0, 24, 48, 72, 96, 120, 144)
We now create two lists and multiply them together with the map and flatten with flatMap.
This is now a Monadic paradigm. We combine the use of flatMap and map together to create something new. However note that the flatMap and map are just syntactic sugar for what this really is which is
val xy2 = for {
xi <- x
yi <- y
}yield ( xi* yi )
Running the for gives you the exact same result. Whilst most collections are monadic in style the idea of a monad does not only apply to collections. For an example let us look at Option using this code.
//However not all Monads are collections. Indeed look at Option
val one = Option(1) /
> one : Option[Int] = Some(1)
val two = Option(2)
> two : Option[Int] = Some(2)
val three = Option(3)
> three : Option[Int] = Some(3)
val four = Option(4)
> four : Option[Int] = Some(4)
val five = Option(5)
> five : Option[Int] = Some(5)
val none: Option[Int] = None
> none : Option[Int] = None
val six = two flatMap( i => three map( _ * 3 ) )
> six : Option[Int] = Some(9)
val sixMaybe = for {
i <- two
j <- none
}yield ( i * j )
> sixMaybe : Option[Int] = None
As you ca see here an option wraps a Some or None as in the real world the value maybe a Null or in Scala a None. However null pointer exceptions can now be handled more elegantly. When we create the val six we can use monadic paradigms with a flatMap and map to get our result.
However you will see that in the for loop we do the same thing but try to multiply 2 and None which in the old days would have blown up in a Null Pointer Exception. However now we can just ask the Option if it has a Some or None and if its None as sixMaybe is we can deal with it elegantly.
People who enjoyed this article also enjoyed the following:
Naive Bayes classification AI algorithm
K-Means Clustering AI algorithm
Equity Derivatives tutorial
Fixed Income tutorial
And the following Trails:
C++Java
python
Scala
Investment Banking tutorials
HOME
