June 14, 2020

Monads

It has been just over 2 years since I last looked at Monads. I gained a partial understanding back in 2018, but gave up and set Haskell aside entirely for about 2 years. Now I am back at it again, and feel like I am making progress.

A number of things got in my way before, so let me address those in case others are tripping over the same things.

One of the things was impatience. I wanted to rush ahead and learn about Monads without taking the time to absorb Haskell type, type classes, and functors -- among other things. All of these are important to understanding Monads in particular and Haskell in general. No short cuts! Haskell is so new, unique, and different that these things need to be examined carefully without any preconceived notions.

The first thing is that a Monad is not a type as we would understand a type in most other languages. In Haskell a Monad is a type class, which may not convey much meaning unless you have carefully and patiently studied types and type classes. Consider a list. A list is a Monad! In other words it belongs to the Monad type class. A list can (and does) belong to several other type classes. The key thing here is that saying that a certain thing is a Monad is not like saying it is an object of type Array in some other language. Saying that it is a Monad just says that it can be treated like a Monad, should we care to do so.

The question now would be, "what does treated it like a Monad" mean. If you understand mathematical things like algebraic systems, you are on the right track. You have things and a set of operators that act on those things in certain ways. We have a set of behaviors that are useful and handy, once we learn to work with them.

At this point, a detour may be worthwhile. I gained my understanding of Monads by patiently working my way through the book "Learn you a Haskell". I would have done well to patiently study Haskell types and type classes -- that is more important than you think, and quite different from other languages. What really did help was reading the chapter on functors. The surprise for me was learning that functors were things that get operated on, not the operators themselves. For example a list is a functor! The key property that makes some thing a functor is that fmap can be applied to it! So, if I have a function that takes a to b and fmap it over a list "L a" I will end up with L b. This is easy enough to understand for lists and plain old map does just this and is probably familiar to most people. But plain old map works only on lists, whereas we can use fmap on any functor. Consider a functor that holds a scalar value (like Maybe). We can take the same function that takes a to b and use fmap to apply it to "Maybe a" and get "Maybe b". Now this is more interesting, and a good stepping stone to understanding Monads.

Jumping ahead to Monads, we may have a Monad "M a". Once again, a Monad is a sort of "container" for a simple type like a. Now suppose we have a function that takes a and produces a Monad "M b". What if we want to map this onto "M a"? The is an operator called a "bind" operator that does just this, and it is quite handy when working with Monads. Enough for now. I need to learn more and clarify all of this as I fine tune my understanding.

More to follow, real soon now .....


Feedback? Questions? Drop me a line!

Tom's Computer Info / tom@mmto.org