Javascript Functor, Applicative, Monads in pictures
--
Inspired by Swift Functors, Applicatives, and Monads in Pictures where the original article Functors, Applicatives, And Monads In Pictures is translated from Haskell into Swift, I would like to write a javascript version for it so that people not familiar with above languages can get the gist of essential functional programming concepts.
Some may feel this is a poor choice as it's against the common understanding that javascript is predominately imperative. However, according to our respectable javascript guru, Douglas Crockford in JavaScript:
The World’s Most Misunderstood Programming Language. “… This is misleading because JavaScript has more in common with functional languages like Lisp or Scheme than with C or Java. …” I believe javascript is equipped with most of functional programming features and fully capable of writing functional code.
Here’s a simple value:
And we know how to apply a function to this value:
Simple enough. Lets extend this by saying that any value can be in a context. For now you can think of a context as a “box” that you can put a value in:
Now when you apply a function to this value, you’ll get different results depending on the containing box. This is the idea that Functors, Applicatives, Monads, Arrows etc are all based on.
In Haskell, Maybe type encapsulates an optional value which is either a value of type a (Just a) or empty (Nothing). It serves as a container referring to the “box” mentioned above where we can put stuff in. In javascript, there is no such thing like Maybe while we can easily see counterparts in other languages, such as Optional in Swift and Java 8, or Option in Scala.
To wrap the value, let’s use Array in javascript to represent a containing box.
Functors
When a value is wrapped in a box, you can’t apply a normal function to it:
This is where map (fmap in Haskell) (<$> in Haskell) comes in. map is from the street, map is hip to containing box. map knows how to apply functions to values that are wrapped in a box. For example, suppose you want to apply a function that adds 3 to the wrapped 2 and assume there’s a map function exist: