3 ms·
Monads embody the concept of "chaining" functions. Every monad implements the chaining in a different way, but the user of the monad doesn't have to know how i
by chuckadams 2y ago
Monads embody the concept of "chaining" functions. Every monad implements the chaining in a different way, but the user of the monad doesn't have to know how it's done. It's just "call this function on foo, take the result and pass it to the next" and so on. Plain old functions do it with plain old function composition (functions are monads!) but something like Maybe will return None if it gets a None, and only otherwise pass the data on. The Future monad will await completion then pass it on (async/await is a monad!), the List monad will merge together zero or more list results from mapping over each of its items, and so on.
Again, the cool thing is that it's the same syntax no matter what kind of Monad you're in, so you can totally change the behavior of a monadic function by just using it with a more specific return type (at least in Haskell, other languages might make you pass around an implementation)
Monads are a neat tool of composition, but composing monads themselves is fiddly and cumbersome, involving monad transformer "stacks" of deeply nested generic types. Monad transformers are really just not fun.
I'd give specific examples, but I'm kind of lethargic from the burrito I had for lunch. If you're familiar with flatMap(), a Monad is anything that's "flatmappable" (which in JS is just arrays, but languages like Scala take it much further). In C#, it's IQueryable (LINQ is a monad!)
- aodonnell2536 2y agoWould it then follow that commands/builtins like `time` and `sudo` are monads? What about shell commands in general, since you can always chain together stdout to stdin with pipes?
- chuckadams 2y agoStreams are definitely monads, so if you're reading lines from stdin and printing zero or more lines for each to stdout, you basically have a List monad (Haskell's laziness makes every list a poor man's stream, though if you're doing serious streaming work, you'd probably want something more specialized). Mind you, shell pipes aren't actually implemented monadically, but you can certainly visualize it that way when working with functional libraries.
- jerf 2y ago"Monads embody the concept of "chaining" functions." No, it doesn't. Monad implementations may call the provided function zero times, or multiple times. Chaining implies exactly once, one of the common misconceptions about the monad interface. Flatmap is another common attractive nuisance; flatmap is the monad implementation for lists but is not "monad" in general, any more than "an iterator on linked lists" is "iterator" in general.
- chuckadams 2y agoChaining implies sticking one function to another, with the implication that some data is being threaded through them. Whatever extra semantics go on top of that are gravy, it's a vague term for a vague concept. I even gave examples where the function might be invoked zero times (Maybe) or multiple times (List). And in some languages (I specifically mention one) flatmap is a function on all monads, not just lists.
- jerf 2y agoIf you understand it correctly, then use correct terms to describe it. And I don't mean the mathematically correct pristine words that some particular FP language uses, I mean, terms that will create correct impressions in the audience and not incorrect ones. You don't help by using the most commonly misunderstood terms and reinforcing the widespread misconceptions about how it works. Both "flatmap" and "chaining" create completely wrong impressions. You just leave people having to clear out the misunderstandings to get to the real and not really that complicated truth.
- deleted 2y ago[deleted]
- deleted 2y ago[deleted]
- chuckadams 2y agoFeel free to jump in with your corrections or suggestions for more appropriate phrasing then instead of sniping at my terminology. I'm done.