top | item 10139696

Effectful Haskell: IO, Monads, Functors

84 points| brassybadger | 10 years ago |slpopejoy.github.io | reply

62 comments

order
[+] nilved|10 years ago|reply
Naming is one area where Haskell's academic background is more curse than blessing. Numerous tutorials and blog posts would never have been written if only functor was named mappable and monad was named computation builder. They're named by analogy to category theory, but their usage in computer science is not at all similar.
[+] ajtulloch|10 years ago|reply
The Haskell monad typeclass _is_ (modulo technical details) a category-theoretic monad on the category `Hask`.

As Edward Kmett says in more detail in [1] - the point of calling a monad a monad is not to confuse the reader, but to unlock 70 years of documentation on the concept for the reader. How many programming concepts/tools/libraries do you use that have 70 years of documentation?

Being abstract is profoundly different from being vague.

[1]: https://yow.eventer.com/yow-2014-1222/stop-treading-water-le... (around the 20 minute mark).

[+] spopejoy|10 years ago|reply
How is the list monad a "computation builder"? Sounds to me like "programmable semicolons" and other nonsense: Monad is a typeclass that means very different things depending on what type you're using. It's the shape that has meaning: this level of abstraction is just going to be hard to grasp correctly no matter what you call it.

Likewise with "Mappable": in most other languages, `map` is only an operation on lists or list-like things. `ask` in `Reader` is implementable with Functor only: by what tortured metaphor does `Mappable` help you understand that? Also it sounds like Java. Yuck :)

Names are a bikeshed. Monad, Applicative and Functor have the advantage of at least being rigorous, I can't see any other name being better.

[+] freyrs3|10 years ago|reply
Their usage in Haskell/OCaml etc is precisely faithful to their category theoretic definitions as can be in a general purpose language.

This debate about naming monads is pretty tiresome after so many years, if one called it "computation builder" it wouldn't change their structure or convey any notion of the laws any better than term monad. A monad at it's core is a set of algebraic relations.

[+] tome|10 years ago|reply
> Numerous tutorials and blog posts would never have been written if only functor was named mappable and monad was named computation builder.

If that were so, monad and functor tutorials would be as follows:

Functor tutorial: imagine it's called "mappable". End of tutorial.

Monad tutoral: imagine it's called "computation builder". End of tutorial

[+] dllthomas|10 years ago|reply
I disagree.

There are some major benefits to the Haskell community's approach of naming abstractions after the math (where a suitable mathematical abstraction exists).

First, as has been mentioned, there are existing treatments of the objects in question, some interesting results there can be ported over to programming, and intuitions there lead new and sometimes useful places. Some newcomers will even be familiar with the concepts already - this is very few people for monad, but far more for monoid and semigroup. It avoids erecting an unnecessary wall between programming knowledge and mathematical knowledge.

Second, it changes the character of a particular kind of discussion: there is never ambiguity about whether a newly considered operation on a type "really" is "appending" - is it associative? does it have an identity? you've got a monoid. This means it's very clear what you can and cannot assume around a particular interface. Questions about whether "functors" are well thought of as "containers" or "mappable" or whatnot are clearly only questions of pedagogy.

[+] danidiaz|10 years ago|reply
The monads that were harder for me to understand while learning Haskell had quite plain names like "State" and "Continuation". I don't think alternative naming would have helped.

By the way, while I'm not sure the monad concept would be useful for all languages, I believe monoid really should become common parlance. It's such a simple and useful idea.

[+] wetmore|10 years ago|reply
A decent indication that it's not as simple as "well just call it x instead" is that each time I see a comment like this there is often a new "easy" word for monad. Yours is new to me, so I'll add it to the list:

Monads are hard, let's call them

- FlatMappable

- AndThenable

- Joinable

- Chainable (or, Daisychain)

- Computation Builder

[+] creichert|10 years ago|reply
Their naming is similar enough to leverage existing research literature, and knowledge, though. Those with a background in math can map some of their existing knowledge. Those without a math background have a more precise vocabulary to understand the concepts and research further. Even if they are a bit foreign, I prefer the attempt to be precise.
[+] spion|10 years ago|reply
My problem wasn't the word but the fact that the word is not adjective - originally I spent a lot of time thinking "where is the monad?". This of course is the wrong question to ask, but if the word was "monadic" instead, then I would've known that this is a property (like iterable, foldable, applicative etc), and realized I should think of typeclasses more in terms of interfaces rather than values.

Sure, their instances (implementations) are values (dictionaries of functions which are implicitly passed around) but thats beside the point when learning.

[+] cousin_it|10 years ago|reply
Yeah, the Haskell culture seems to have a problem with naming. It uses a lot of mathematical terms and a lot of alphabet soup identifiers. Part of the problem is just that naming highly abstract things is hard (what would be a meaningful name for the monadic return operation?) Another part is that the commercial programming world has developed a whole art of naming things so that a maintenance programmer can understand them easily, but the Haskell community doesn't want to use that art because it reminds them of Java or something.
[+] jtaylor100|10 years ago|reply
This article has successfully caused me to understand what a monad is.
[+] lobster_johnson|10 years ago|reply
Something I've wondered about: How does Haskell not optimize away IO ()? In a pure, functional languages, a function that doesn't return anything can simply be eliminated — but of course it isn't.

I've always assumed that Haskell's compiler has a built-in rules about IO having side effects, but I never actually bothered to find out.

When I first started with Haskell, one of many small epiphanies was when I realized that the IO monad itself doesn't actually do anything. bind and return don't do anything except wrap and unwrap values, and there's nothing that checks if you are in some kind of "IO context" to permit things like file I/O. There's no magical "side-effectful computation chain engine" behind the scenes.

[+] erydo|10 years ago|reply
IO is the type, not the value. Something that takes IO and returns IO wouldn't be optimized out for the same reason a negation wouldn't be optimized out simply because it takes an Int and returns an Int.
[+] heroku|10 years ago|reply
"We can see therefore how Monad offers strictly more powerful transformations than Functor. fmap can only transform an individual value “in place”, while >>= can return an empty list, or a list with more elements than the original. Functor is “structure preserving”, while Monad is “structure transforming”."

So for a list monad bind = flatMap fmap = map

is that correct?

Studying FP for quite a while first monad tutorial I come to fully understand finally.

[+] chriswarbo|10 years ago|reply
> So for a list monad bind = flatMap fmap = map

> is that correct?

Yes, although Haskell calls "flatMap" "concatMap". Of course "return" is just "\x -> [x]", AKA "(: [])".

Instead of bind (">>="), you can implement Monads using "join" instead. For lists, "join" is simply "concat".

[+] aikah|10 years ago|reply
So is it possible to explain monads with Javascript ? or even LISP ? seems to me monads == haskell so if one doesn't understand haskell one can't understand monads , cause all monad tutorials are written in haskell. So I ask , what is the point of learning what a monad is if i'm writing some Java ?
[+] spion|10 years ago|reply
Yes. Infact, a JavaScript Promise is pretty much the same as the IO monad* - the `then` method is a lot like `bind`. Promise.resolve is a lot like `return`

* almost the same to IO, because of recursive thenable assimilation, something that was added to promises but is totally short-sighted and unnecessary; and because promises are eager which means they don't represent the action to be executed, but the value of an already executed action

[+] nightski|10 years ago|reply
It is possible to implement monad-like behavior in javascript. But javascript does not have a type system to model them in.

Haskell is great because it's type system is rich enough to represent these concepts and not only that but enforce their usage (to a degree). Unfortunately this is like a drug, once you get a good dose of Haskell it's easy to crave an even richer type system with dependent types.

[+] kilovoltaire|10 years ago|reply
For one example, Scala's `for` syntax is quite similar to Haskell's `do` notation, and lets you do some monadic things with `Option`, `Seq`, and other classes.

And then you can go much further into that world with the scalaz library.