> Monads are not complicated. They are implemented as a typeclass with two methods, return and (>>=) (pronounced "bind"). In order to implement a Monad instance, these two functions must be defined in accordance with the arity described in the typeclass definition:
This is a great example of what I just said: it uses complex Haskell code and functions to describe a monad. If you already know what it assumes you know, you most likely already know what a monad is.
Monads are very simple. They just aren't easy because most people don't have the base of terminology. When you grok them you'll laugh because you'll realize how simple and powerful and obvious they seem in hindsight.
This is the reason so many people write monad tutorials after they learn them. It's actually really weird. Does anyone else have some examples of things they learned which seemed really difficult but turned out to be really simple in hindsight?
Sure: everything.
Everything is complicated until you learn it, and then it looks simple in hindsight.
You're just confirming what OP said: it's not easy to come across an article explaining monads or Haskell that doesn't implicitly rely on the fact that the reader already understands monads or Haskell.
Beautiful insight. I now realize that simple and complex are about the concept being learnt, and easy and and hard likely to be about the process of learning. There would be correlation in general, however, not always. :-)
I have seen many examples of things which are easy at the end, but the process of reaching there was hard, sometimes because of initial ignorance of my own or of mankind overall.
I wish I could take credit for this one! I learned the distinction from a (rather famous) Rich Hickey talk. [0]
I've had this happen for
- everything from linear algebra (at least 20 things) - all kinds of stuff from mathematical optimization - inequalities, which are really difficult until something "clicks" and then when to apply them becomes obvious, cauchy-schwartz and jensen's in particular - induction (this was a long time ago / early in my math career) - diagram chases - the entire typeclass stack from FP (functor applicative monad, then all the monad interfaces) - huge chunks of axiomatic probability and measure theory (what do sigma algebras really mean, what is a good definition for integration, what is continuity of measure, dinkin's pi-lambda theorem) - and so it goes on
I am still waiting on some of the following things to click so that I may abuse them productively as well:
- LLL - yaos min-max theorem - lots of results from logic
I surmise this happens for monads and freaks developers out because it's one of the few pieces of serious math (i.e. no handwaving, given as a rigorous construction, etc) most people come across, so the phenomenon catches people off-guard.
If you like this thing, do more math!
things that are very similar to other things when expressed concretely, but actually exist at different levels of abstraction? things that are counter-intuitively awkward to express by way of examples, because too many things are examples, sometimes in multiple subtly different ways?
adjunctions (etc.) in category theory seem like 'above paragraph : the movie', but i can't claim to understand them in full generality so i'm unsure.
Yeah, we don't care for simple. Can you explain them in an EASY way?
That's like saying a giant, complex library with a nice, tight API is 'simple'. It's not, the complexity is just hidden.
Same thing with monads. Once you understand some of the machinery of category theory, or really grok functional programming, then yes, monads are 'simple', but all the complexity lies in getting there.
Monads can be two things: (1) a concept in category theory, (2) a rough implementation of that concept in a programming language.
If you want to learn about monads from the category theory perspective, great! This is really hard though, I wouldn't recommend it for most people (and haven't really even succeeded myself).
If you want to learn about a specific programming language's implementation of monads, you will naturally have to know how that language works. This road is far easier than category theory, but still requires knowing (for Haskell) what a typeclass is, what a higher-kinded type is, etc.
It sounds like you want an explanation without prereqs from either category theory or Haskell. If you google for monad tutorials you will find dozens of quick explanations, but I personally don't think this is a good way to actually understand them.
You can do that with the y-combinator but why not monads?
http://www.kylheku.com/cgit/lisp-snippets/tree/monads.lisp
Apologies for there not being a use example for the state transformer monad/comprehension. I can whip one up if needed.
You need types. Then you need "higher order types" or parameterized types. Then you need a way to discuss a common set of operations which appear repeatedly for some of these parameterized types and it can't be OO-like.
You can exemplify the operations in, e.g., Lisp, but you have a hard time "talking about" the thing.
---
In Scheme, monads are the answer to the following question:
The functions (define (pure a) (list a)) and (define (join ls) (foldl append (list) ls)) are related to lists in the same way that (define (pure a) (lambda (k) (k a))) and (define (join z) (lambda (k) ((z k) k))) is related to CPS-transformed programs. What is the commonality?
You take a c++ parent class with two virtual methods. These methods are "return" and "bind". In order to implement a monad instance you must derive from this parents class and implement the virtual methods.
return takes a value and returns an instance of your template class containing the value.
bind takes an instance of your (template class A) a function of (type a ) to (template class B) and produces a value of (template class B).
If you don't care about the "laws" your definitions are expected to follow thats it.
The idea bind is you take a value of a template class such as (std::vector<Int> type) the value {3}, then based on value either pass it to the next function or return it.
one definition of bind would be if the vector is empty return it, if its not empty pass it to this function and return the result of that function.
return is just a way of placing a value into your template container class.
I'm not even saying that a bit sarcastically. I've read countless "tutorials" and even tried messing around with Haskell in an attempt to grok monads. According to the link shared by GP comment, my understanding is still completely wrong.
There is a reason there is a joke about it.
"A monad is just a monoid in the category of endofunctors, what's the probleⅿ?" - James Iry, taken from [0]
[0] http://james-iry.blogspot.com/2009/05/brief-incomplete-and-m...
My favourite monad explanation is Tikhon Jelvis's at https://www.quora.com/What-are-monads-in-functional-programm..., but reading through it, it does assume some prerequisite knowledge about Haskell.