[Disclaimer: I am still trying to fully grok monads. The following is just what I have understood so far. If it’s wrong, hopefully someone knowledgeable will call me on the carpet.]
Arnar wrote:
Monads are simply a way to wrapping things and provide methods to do operations on the wrapped stuff without unwrapping it.
That’s precisely it. The idea goes like this:
You take some kind of value and wrap it with some additional information. Just like the value is of a certain kind (eg. an integer or a string), so the additional information is of a certain kind.
E.g., that extra information might be a
Maybeor anIO.Then you have some operators that allow you to operate on the wrapped data while carrying along that additional information. These operators use the additional information to decide how to change the behaviour of the operation on the wrapped value.
E.g., a
Maybe Intcan be aJust IntorNothing. Now, if you add aMaybe Intto aMaybe Int, the operator will check to see if they are bothJust Ints inside, and if so, will unwrap theInts, pass them the addition operator, re-wrap the resultingIntinto a newJust Int(which is a validMaybe Int), and thus return aMaybe Int. But if one of them was aNothinginside, this operator will just immediately returnNothing, which again is a validMaybe Int. That way, you can pretend that yourMaybe Ints are just normal numbers and perform regular math on them. If you were to get aNothing, your equations will still produce the right result – without you having to litter checks forNothingeverywhere.
But the example is just what happens for Maybe. If the extra information was an IO, then that special operator defined for IOs would be called instead, and it could do something totally different before performing the addition. (OK, adding two IO Ints together is probably nonsensical – I’m not sure yet.) (Also, if you paid attention to the Maybe example, you have noticed that "wrapping a value with extra stuff" is not always correct. But it’s hard to be exact, correct and precise without being inscrutable.)
Basically, "monad" roughly means "pattern". But instead of a book full of informally explained and specifically named Patterns, you now have a language construct – syntax and all – that allows you to declare new patterns as things in your program. (The imprecision here is all the patterns have to follow a particular form, so a monad is not quite as generic as a pattern. But I think that’s the closest term that most people know and understand.)
And that is why people find monads so confusing: because they are such a generic concept. To ask what makes something a monad is similarly vague as to ask what makes something a pattern.
But think of the implications of having syntactic support in the language for the idea of a pattern: instead of having to read the Gang of Four book and memorise the construction of a particular pattern, you just write code that implements this pattern in an agnostic, generic way once and then you are done! You can then reuse this pattern, like Visitor or Strategy or Façade or whatever, just by decorating the operations in your code with it, without having to re-implement it over and over!
So that is why people who understand monads find them so useful: it’s not some ivory tower concept that intellectual snobs pride themselves on understanding (OK, that too of course, teehee), but actually makes code simpler.
- 119.5k
- 24
- 102
- 101