Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Each of your statements seems plausible, even profound in itself.

Then I try to combine them and my head explodes.

You don't need to understand Monads to understand Haskell but they're how you print "Hello world"?? Yeah. Your other example also seem pithy and worthy, and again leave me feeling like the result is utterly opaque. You've shown goodness and power and all but it feels like you're holding the real definition behind your back to make the magic look even more magical-er.

How's-about-ya-spit-it-out. What the heck's a monad?

I feel like I've gotten as far as thinking that a monad's like a little interpreter/pre-interpreter. You pass it something like raw code and it binds more meaning to the variables as well as change the context of execution etc, all before that code gets eventually interpreted. Kind of like how you pass fragments of code to Ruby functions and kind of like how c++ templates are parameterized by type.

Wikipedia says "A monad is a construction that, given an underlying type system, embeds a corresponding type system (called the monadic type system) into it (that is, each monadic type acts as the underlying type). This monadic type system preserves all significant aspects of the underlying type system, while adding features particular to the monad." http://en.wikipedia.org/wiki/Monad_(functional_programming) At least that definition doesn't leave me feeling like someone's said "I can't tell you but they're really great"...



No, actually, i've read dozens of explanations, i went metalinguistic and read discussions about discussions of monads, and this guy is totally correct, the ONE SINGLE most important thing to know about a monad, it would seem, is that you are not required to know what a monad is to use it.


You're right - I didn't explain what a monad is a priori, just some of their properties and reasons they're useful. Thanks for calling me out on that, as I should have made it more explicit.

I didn't mean to "hold the real definition behind my back", just felt that others in this thread had explained the definition better than I could. I also wanted to make the point that the definition is not that important unless you actually want to implement your own monad.

You don't need to understand Monads to understand Haskell but they're how you print "Hello world"??

Yes, there's no contradiction here. The idiomatic and easiest way to write Hello World in Haskell involves some unusual, but fairly intuitive, imperative-looking syntax. That syntax only works because the Haskell IO API is monadic, but you really don't need to know that, nor to understand what a monad is, in order to print Hello World.

LINQ is very similar to Haskell's do-notation, and LINQ providers (LINQ-to-Objects, LINQ-to-SQL etc) are monadic, but you don't need to know what a monad is to write "from u in users where u.age > 21 select u.name". If you want to write your own LINQ provider, though, it's probably worth knowing the monad laws.


For a more thorough, probably better written although longer explanation, I say going to http://blog.sigfpe.com/2006/08/you-could-have-invented-monad... and reading through that, but I'll give it my own, shorter go and see if you can follow.

Monads are basically a design pattern dealing with special data types. Let's say you're in some situation where there's nondeterminism—each function doesn't return just a value, but several possible values. To use a pseudo-C++-like type system, all of your functions have a signature like

    List<B> doSomething(A);
where it returns a list of B's to represent every possible value. You want to chain these together, and the naïve way is

    foo = doSomething(x)
    bar = []
    for someFoo in foo:
        bar += doSomethingElse(someFoo);
    baz = []
    for someBar in bar:
        baz += doSomeOtherThing(someBar)
So for every function, you have to repeatedly accumulate the possible values for every possible value so far. If you have higher-order functions, you can encapsulate this in a function like this

    def bind(f, list):
        results = []
        for value in list:
            results += f(value)
        return results
which means the above example could be rewritten as

    bind(doSomeOtherThing,
         bind(doSomethingElse,
              bind(doSomething, [x])))
Now, the type of bind looks something like

    List<B> bind(List<B> f(A), List<A>)
which is to say it takes a function from a normal type to a "special" type—in this case a list—and applies it to a "special" type—in this case, every element of a list. In this case, we'd say that List, together with the bind function, is monadic. The Haskell types look more like

    bind :: (a -> m b) -> m a -> m b
    -- or for our particular example
    bind :: (a -> [b]) -> [a] -> [b]
The key here—and it's a simple example, so it's probably hard to see how it extends to the hype given—is that you've got a "special" kind of data and you're taking functions which operate on normal (non-special, in this case, non-list) data and writing functions to use them on special data with little work. The cool thing is that it's a really common pattern, which is why Haskell programmers mention it a lot.

(Note: in Haskell, 'bind' is actually an operator written >>=, and the order of its arguments are reversed, so its type is

    >>= :: (Monad m) => m a -> (a -> m b) -> m b
but there are reasons for writing it the way I did.)




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: