A monad is any data structure which implements bind. Bind is a higher-order function with two parameters - one is the data structure to be transformed, the other is a function which maps over elements in the data structure. However, unlike a normal map, each result of "bind" sits in its own version of the original data structure, which then have to be combined back into a single data structure. The way in which the data structures are combined is what makes each monad different.<p>For example, List is a monad. Suppose we had a List of Ints, such as [5,3,4]. If we were to run bind over this list, we would need a function that takes an Int and returns a List of something. We could use "show", the function which converts Ints to Strings (a String is technically a List of Char. Since this is a List, we're good). If we call bind using [5,3,4] and show, we get ["5","3","4"] which are then combined to "534".<p>We can check with the interpreter (>>= is bind):<p>Prelude> [5,3,4] >>= show<p>"534"
My general problem with Haskell articles and such: they are written as if you already understand Haskell. They make total sense if you know the language, but if you are trying to learn are mostly useless if not more confusing. Or even worse, they devolve into dense academic prose even when writing introductory articles.<p>Sometimes they even use Haskell as if you already know it to try to explain it.<p>I'm still looking for a basic article that describes monads well. My first few languages were all functional too, so that isn't the problem. I even still use APL derivatives.
I'm still kind of having problems with monads. Funnily enough, I recently found an article explaining what monoids are: <a href="https://fsharpforfunandprofit.com/posts/monoids-without-tears/" rel="nofollow">https://fsharpforfunandprofit.com/posts/monoids-without-tear...</a><p><pre><code> You start with a bunch of things, and some way of combining them two at a time.
Rule 1 (Closure): The result of combining two things is always another one of the things.
Rule 2 (Associativity): When combining more than two things, which pairwise combination you do first doesn't matter.
Rule 3 (Identity element): There is a special thing called "zero" such that when you combine any thing with "zero" you get the original thing back.
With these rules in place, we can come back to the definition of a monoid. A "monoid" is just a system that obeys all three rules. Simple!
</code></pre>
Long explanation overall in the article, but based on 6th grade math. I understood it, and it stuck. Could someone extend the monad explanation from here? Maybe I'll finally get it :)
Monads are not complex. A monad is a box. Any monad has two functions (plus others, imagine this is a minimal interface): bind and return.<p>You can put anything in the box. It's TARDIS-like.<p>`return` replaces the thing that was in the box.<p>`bind` replaces the box.<p>Most monads have a number of functions that can only be executed over boxes. This is because the boxes have special metadata (for example, someone has been scribbling state underneath the box). The 'get' function from the State monad just tells you to read the gibberish on the box instead of unpacking the box. The 'set' function scribbles more stuff on the bottom of the box.<p>Useful monads then provide a function to put things into the box, work with the box and then throw the box away (or inspect it by itself). These are the functions called 'runWhatever' for example 'runState', which lets you put an apple in the box, put a shipping label onto the box and then eventually separate the apple and the shipping label into each hand, throwing the box in the bin.<p>You can put anything in a box. Even more boxes. And when you're inside the box, you can't really tell how deep you are. If you're in the bottom box you can't actually see that you're in 20 layers of boxes, and this is why Monads are so powerful for creating libraries and frameworks.
IMO the most accessible resource for learning functional concepts like Functors, Applicatives and Monads is the free online book: <a href="https://github.com/MostlyAdequate/mostly-adequate-guide" rel="nofollow">https://github.com/MostlyAdequate/mostly-adequate-guide</a><p>It uses Javascript to explain everything from scratch. Pure-functions, currying, composition, functors, monads, applicatives and so on.<p>Its free, so check it out. Reading it and understanding the concepts completely changed my whole coding style in the last couple of month. I hope functional javascript becomes more mainstream and we will soon call this stuff 'standard'.
Its just too convenient to stack a Future on top of a Reader and get dependency injection + async function handeling without any boilerplate code.<p>P.S. Since ES6, javascript is wonderful. Functional code often really looks like lisp. Pity that we don't have macros (yet, and actually there is a way (sweet.js).<p>P.P.S. If DrBoolean got you hooked. You might want to check Ramda and fantasy-land. The former is a more functional minded underscore/lodash, the latter a specification (and community) for algebraic data structures in javascript to which a lot of new libraries adhere to.
To everyone new to haskell and confused: Don't judge haskell based on these definitions. They appear strange and crazy, but when you actually do stuff most of them turn out to be quite intuitive.<p>My advice is to ignore these things. Don't read a million monad tutorials. Just play around and code something, you don't have to understand the monad-definition before you can use the do-notation. Try to ignore them. After a while you get an intuition and then the definitions will make sense.
This is a good start and might be useful to other beginners. From the vantage point of someone who already knows what the words mean, I can fill in the gaps in your definitions but unfortunately, a beginner might not be so able.<p>Here are some suggestions on how you might close some of those gaps a bit (I think allowing yourself to go over a sentence here and there should be ok).<p>You use fmap more than once without having defined it.<p>Currying: You need to define partial application.<p>Map and filter, I'd use collection instead of list. There is more nuance but that is good enough at this level.<p>Morphisms generalize the concept of function. They can be thought of as capturing structure (such as a set equipped with + and 0) preserving maps (which is something analogies try to do).<p>lazy evaluation could do with mentioning thunk, then you'd have to define what a thunk is, of course.<p>Fold: Folds are a lot more interesting and it's not clear what you mean by your given definition. I suggest defining it in terms of structural recursion.<p>Category: It's worth defining what objects mean to a category. As well, explicitly mentioning the laws of identity, composition and associativity rather than just the nebulous wording of configuration would be beneficial.<p>Functor: A more useful foundation is in thinking of functors as morphisms between categories.<p>Types: There is much more to types than this. Wrong in the correct direction is to think of types in terms of sets. Better yet, as propositions.<p>Type Classes: Since you mention parametric polymorphism, you should also mention ad-hoc polymorphism and how type classes and interfaces are examples.<p>algebraic data types: There's a lot more to algebraic data types than this. After defining sum types and product types elsewhere, you can talk about why such types are called algebraic.<p>parametric polymorphism: what is a type variable?<p>monoid: Moniods also need an identity element, and giving examples is always useful: natural numbers: +,0 or strings: +,"". One reason monoids are of special interest to computing is because they possess associativity, which is useful when parallelizing.
Jargon from the functional programming world in simple terms! <a href="http://git.io/fp-jargons" rel="nofollow">http://git.io/fp-jargons</a>
> A monad is composed of three functions<p>Actually just two (bind and return). And three laws which are typically not captured in the type system and which must therefore be tested separately.
One simplistic but useful analogy I've found is that monads are a way to control program flow with functions. A monad is to functional programming what if/else is to imperative.<p>It may not cover all the nitty gritty about what is and isn't a monad. But it gets you a long way to understanding why you might use them.
Question to JS people using Redux. Are the middlewares used to control side effects in actions considered monads? The action returns a description of the side effect, and the middleware handles the actual doing, leaving the programmer to focus on the pure aspects.
These sentences are nice, but I feel like more definitions and some re-ordering could make the document as a whole more meaningful.<p>For example, Lift is defined way before Functor, and fmap is never defined so I had no idea what Lift was about despite that nice concise sentence.
What an excellent distillation!<p>It isn't uncommon to see someone w̶i̶t̶h̶ ̶a̶ ̶f̶r̶a̶g̶i̶l̶e̶ ̶e̶g̶o̶ explain this stuff in a way that is needlessly complex and full of jargon that scares folks off.<p>Thanks for the great work here. We need more of this kind of thing in the FP world!
There is an adage that if you see a lot of advertising for a medicine (think hair regrowth formulas, or pills of reflux disease) you know that none of them are any good.<p>This page makes me wonder about monads in the same way.
Hmm. They certainly have a naming and explanation problem in Haskell land. Some impressions from a few of these better explanations.<p>"A monad is composed of three functions and encodes control flow which allows pure functions to be strung together."<p>Gibberish compared to claim that monads just execute functions in a specified order. Aka an imperative function or procedure by one definition I've seen a lot. Of course, that monad definition might be wrong, too.<p>"A recursive function is a function that calls itself inside its own definition."<p>That's a recursive definition lol. Must have been a joke.<p>"A monad transformer allows you to stack more than one monad for use in a function."<p>We've had composition of procedures for a long time. Perhaps Haskell could've called it a MonadComposer?<p>"Lift is an operation on a functor that uses fmap to operate on the data contained in the functor."<p>fmap-apply() or something like that?<p>"Optics(lens and prisms) allow you to get and set data in a data type."<p>Getters and setters. My early OOP/C++ books are finally more intuitive than something.<p>"Map applies a function to every element of a list."<p>foreach(function(), list)<p>"A predicate is a function that returns true or false."<p>A boolean function.<p>"Filter applies a predicate to a list and returns only elements which return true."<p>Syntactic sugar for a foreach(function, list()) where the function on each member is an If (Conditional) is TRUE Then AddElementToNewListThatsReturned(). Yeah, even the description of imperative version is getting long. This might be a productivity boost.<p>"A morphism is a transformation from any object to any other object."<p>A cast from one object to another? Or one with an actual conversion function and/or check? The functional name seems more accurate, though.<p>"Algebraic data types are a method to describe the structure of types."<p>Ahh, they're just structs. Wait, what is a type exactly? And therefore what is an abstract... oh darn...<p>"Free monads allow the transformation of functors to monads."<p>A functor is an object that can be fmaped over. We covered map. Maybe the same. A monad is either an ordering of functions or something composed of three functions and encodes control flow composed of pure functions. Free monads are apparently an unknown thing that can transform objects that can be fmaped over into something composed of three functions with encoded control flow of composed, pure functions. I heard a lot of good Masters and Ph.D. proposals before this one. This is good, though. Especially quantifying the unknown aspects with a lot of NSF-funded R&D.<p>"A lambda is an unnamed function."<p>"Types are an inherent characteristic of every Haskell expression."<p>"Currying uses partial application to return a function until all arguments are filled."<p>"A category is a collection of objects, morphisms, and the configuration of the morphisms."<p>Ok, I just have fun with that one. Author did good on a lot of them. I'm just going to leave these here as quotes to add to Free Monads in... The Advanced Course: Haskell in Two or More Sentences. They provide anywhere from no information at all to the uninitiated to extra confusion inspiring taking or avoiding Haskell courses. :)