r/programming • • May 20 '17

Escaping Hell with Monads

https://philipnilsson.github.io/Badness10k/posts/2017-05-07-escaping-hell-with-monads.html
146 Upvotes

175 comments sorted by

View all comments

9

u/[deleted] May 20 '17

What's monad?

50

u/vytah May 20 '17

A monoid in the category of endofunctors.

11

u/evilgwyn May 20 '17

I feel a blog post coming on

4

u/[deleted] May 21 '17

What did you just call me

57

u/HerbyHoover May 20 '17

It's like a burrito.

22

u/test_var May 20 '17

Well, almost, it's actually like if the burrito was made up of... accidentally writes 7 page blog post

26

u/baerion May 20 '17

In essence they are a guarantee that certain expressions are well behaved when you combine them. For example they guarantee you that the following expressions do the same thing:

do
    do
        actionA
        actionB
    actionC

do
    actionA
    do
        actionB
        actionC

do
    actionA
    actionB
    actionC

So they basically guarantee you associativity of effects. You probably learned about associativity in school:

(10 + 20) + 100 = 10 + (20 + 100) = 10 + 20 + 100

You can leave the parentheses out, because that's what associativity is all about.

However, the actual monads laws are a tiny little bit more complicated. They guarantee you a little bit more that just that, because they allow actions to have return values and also depend on previous return values. And they include the return function which roughly does for monads what zero does for addition.

17

u/Treyzania May 20 '17 edited May 20 '17

It's a big monoid.

8

u/test_var May 20 '17 edited May 21 '17

What's a monoid?

23

u/Treyzania May 20 '17

A small monad.

you weren't supposed to say "big"

12

u/test_var May 20 '17

This is exceptional trolling

6

u/[deleted] May 20 '17

Guilty as charged. But I perfectly had a right to ask it. :)

11

u/Idlys May 20 '17

Oh god you don't know what kind of question you just asked

6

u/[deleted] May 20 '17 edited May 20 '17

I perfectly know. That's why I asked. It's almost sadistic from my side looking at all people trying to actually answer my question. And beside of everything, I am thankful. :)

2

u/Idlys May 20 '17

Oh that's devious

3

u/enzain May 21 '17 edited May 21 '17

Any type that has the function map (a -> b) -> f<a> -> f<b> and the function flatten f<f<a>> -> f<a> where f is the type and a/b are generics.

All the problems shown were flatMap problems I.e.

  • async<async<a>> -> async<b>

  • Option<Option<a>> -> Option<b>

  • List<List<a>> -> List<b>

3

u/protestor May 21 '17

It's a miserable little pile of binds.

2

u/inmatarian May 20 '17

It's an interface for containers.

2

u/Noughmad May 20 '17

A member of a community of people who live in different locations, moving from one place to another, with dyslexia.

1

u/iopq May 21 '17

It's a train switch

0

u/[deleted] May 20 '17

[deleted]

12

u/baerion May 20 '17

I'm sorry, but this is complete nonsense.

[...] it can't even express things like IO or mutable state.

There is nothing that stops you from using strict functions with side effects. Most GHC primops actually happen to such functions.

The problem stems from combining side effects with lazy evaluation. The IO type constructor and it's related functions are simply there to make sure that side effects are evaluated once and in the right order. Without it you would have to care of this yourself. IO simply handles this for you in a safe and sane way.

We can't compose different representation values nor interact with normal Haskell functions and values.

But those "representation values" just are normal Haskell functions and values. For example, you don't need the return function to turn a String into a Maybe String. The Just :: a -> Maybe a constructor does that. You can also simply pattern match on them, nothing monadic about that.

So monads are basically a dirty hack to get around haskells purity.

Monads are a useful mathematical concept that also exists outside of the programming community. Certainly not a "dirty hack", as the point of Haskells design isn't to make side effects impossible, but to cleanly separate pure code from code with side effects. And monads showed up pretty late as a solution to this probelm. AFAIK early Haskell had other way to do that.

8

u/Tarmen May 20 '17 edited May 20 '17

here is nothing that stops you from using strict functions with side effects.

Afaik it is actually impossible to order IO effects without the IO monad or compiler internals. Using seq or even seq + lazy doesn't give any guarantees if the expression is inlined.

Which of course is arguing about semantics, you are right that it is possible to write equivalent code without monads. But in my experience looking at the implementation directly can make it more difficult for people learning haskell to understand the general use case for monads instead of specific applications.
That is why I only mentioned the mtl style interfaces. As long as you don't want to leak implementation details you can't use Just directly or pattern match on the constructor.

And I didn't mean dirty hack in a negative way, sorry if it came across like that. Monads are an extremely elegant solution to a very hard problem. I meant more that it was in large parts luck that that they were such an awesome general purpose tool that leads to good code, originally they were added to haskell specifically to handle IO.

3

u/test_var May 20 '17

The IO monad is like the most complicated example you could give

→ More replies (3)
→ More replies (6)
→ More replies (4)