Welcome to episode 3 of Scary Words in Programming! (with updates from comments)
Functors & Monads (a twofer!)
Yesterday, my new buddy (from StrangeLoop), Brian Lonsdorf and I did a Hangout on Air in which he explained monads to me (that was the deal). But first, he explained functors! Thus, you all get a twofer post.
However, sad news. You get what you pay for with free things, and apparently Youtube/Hangouts+ has killed my recordings “because they were too long,” and it’s a known bug in Hangouts, according to the product forums. I’m quite disappointed, and still trying to hunt them down, so I’ll let you know if I find them.
In the meantime, more on me to somehow explained what I learned in words.
So, along the conversation and demos Brian walked me through, I learned:
A functor is a
function data type that leverages map().
A monad leverages flatmap() (or chain() or other ways of writing that), working within the same type.
Ripped from the comments (because Michael Ficcara is awesome):
Functor and monad are both names for interfaces. A data type that conforms to the functor interface must implement a map function. A data type that conforms to the monad interface must already be a functor (specifically an applicative functor) and must implement a bind/flatMap/chain function and a return/unit/of function.
As we discuss in the video I don’t have, the most difficult thing about these concepts is that they’re abstract. Seeing it in action can help. In the gist, I created (from memory, may contain errors) what Brian walked me through, where he showed a map function that returns a container, whereas flatmap does not include that container (it is a _flat_ map).
Regular map is awesome, but flatmap gets us to chaining, which can be extra awesome. Update: Check out Michael’s gist that implements the Maybe monad, which is more useful than this identity monad.
Reminder: what does map do? It performs an operation on a value
in place in the same kind of container*. Anything that does that is a functor. Meanwhile, flatmap/monad-like things do the same thing, but they don’t modify the container, i.e. it’s type safe.
In Brian’s examples, he talked about how by using data structures such as these, you could, for example, check ONCE if a value is as expected, and then chain onward. If the value returns a value you don’t want to continue operating on, you stop right there, and don’t have to build more checks into your system.
I really hope I can rescue the video, but if not, hopefully this makes monads and functors a little less scary!
*Updated in response to comment. ex. [1,2,3].map(…) returns an array that has those modifications performed on it, but the original [1,2,3] did not change