by crystalPalace on 3/26/17, 1:27 AM with 165 comments
by scottmsul on 3/26/17, 5:06 AM
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".
We can check with the interpreter (>>= is bind):
Prelude> [5,3,4] >>= show
"534"
by jnordwick on 3/26/17, 4:45 AM
Sometimes they even use Haskell as if you already know it to try to explain it.
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.
by oblio on 3/26/17, 12:38 PM
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!
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 :)by aetherspawn on 3/26/17, 10:30 AM
You can put anything in the box. It's TARDIS-like.
`return` replaces the thing that was in the box.
`bind` replaces the box.
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.
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.
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.
by mpfundstein on 3/26/17, 7:59 PM
It uses Javascript to explain everything from scratch. Pure-functions, currying, composition, functors, monads, applicatives and so on.
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.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.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.
by LeanderK on 3/26/17, 3:47 PM
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.
by rawicki on 3/26/17, 10:33 AM
by Cybiote on 3/26/17, 9:56 AM
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).
You use fmap more than once without having defined it.
Currying: You need to define partial application.
Map and filter, I'd use collection instead of list. There is more nuance but that is good enough at this level.
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).
lazy evaluation could do with mentioning thunk, then you'd have to define what a thunk is, of course.
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.
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.
Functor: A more useful foundation is in thinking of functors as morphisms between categories.
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.
Type Classes: Since you mention parametric polymorphism, you should also mention ad-hoc polymorphism and how type classes and interfaces are examples.
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.
parametric polymorphism: what is a type variable?
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.
by iamwil on 3/26/17, 4:41 AM
by init0 on 3/26/17, 8:03 AM
by bonoetmalo on 3/26/17, 4:14 AM
by edem on 3/26/17, 9:39 AM
by hota_mazi on 3/26/17, 6:17 AM
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.
by burticlies on 3/26/17, 5:49 AM
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.
by strictfp on 3/26/17, 10:07 AM
by babbeloski on 3/26/17, 4:37 PM
by ncphillips on 3/26/17, 7:50 PM
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.
by csneeky on 3/26/17, 1:14 PM
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.
Thanks for the great work here. We need more of this kind of thing in the FP world!
by mbfg on 3/26/17, 5:42 PM
This page makes me wonder about monads in the same way.
by jpt4 on 3/26/17, 3:53 AM
by dmead on 3/26/17, 4:46 AM
by leshow on 3/26/17, 9:12 PM
A monoid is a a type with an associative function and an identity function
by a_imho on 3/26/17, 9:38 AM
by bogomipz on 3/26/17, 12:58 PM
by nickpsecurity on 3/26/17, 5:20 AM
"A monad is composed of three functions and encodes control flow which allows pure functions to be strung together."
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.
"A recursive function is a function that calls itself inside its own definition."
That's a recursive definition lol. Must have been a joke.
"A monad transformer allows you to stack more than one monad for use in a function."
We've had composition of procedures for a long time. Perhaps Haskell could've called it a MonadComposer?
"Lift is an operation on a functor that uses fmap to operate on the data contained in the functor."
fmap-apply() or something like that?
"Optics(lens and prisms) allow you to get and set data in a data type."
Getters and setters. My early OOP/C++ books are finally more intuitive than something.
"Map applies a function to every element of a list."
foreach(function(), list)
"A predicate is a function that returns true or false."
A boolean function.
"Filter applies a predicate to a list and returns only elements which return true."
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.
"A morphism is a transformation from any object to any other object."
A cast from one object to another? Or one with an actual conversion function and/or check? The functional name seems more accurate, though.
"Algebraic data types are a method to describe the structure of types."
Ahh, they're just structs. Wait, what is a type exactly? And therefore what is an abstract... oh darn...
"Free monads allow the transformation of functors to monads."
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.
"A lambda is an unnamed function."
"Types are an inherent characteristic of every Haskell expression."
"Currying uses partial application to return a function until all arguments are filled."
"A category is a collection of objects, morphisms, and the configuration of the morphisms."
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. :)