Hacker News new | comments | show | ask | jobs | submit login
Ask HN: Are Monads Really That Hard?
6 points by biscarch 1718 days ago | hide | past | web | 8 comments | favorite
I've been experiencing something lately. I don't understand the difficulty of monads. So here I present my understanding of Monads in the hope that someone will be able to point me in the right direction, or at least point out something that I'm missing.

* Monads Hide Failure (kinda)

Monads allow you to call a function that may or may not (Maybe/Just/Nothing) return the value you need in the next function. If Nothing is returned, you can pass Nothing through your future function calls or composed functions with no ill effects.

* Nesting Monads

You can nest Monads, or use do notation, to create easily replaceable failure possible sections of code.

    foo :: Maybe Integer
    foo = do
        x <- someMonadicFunction
        y <- someOtherMonadicFunction
        Just (x + y)
someMonadicFunction and someOtherMonadicFunction can be anything that returns Nothing or Integer and it doesn't matter if they fail because the do will return Nothing in that case.

# End

I keep reading about how Monads are a really hard topic, so I think it's possible that I'm not looking at the right pieces here.

So my question is, where do I go from here? Do I understand Monads, or am I missing something here?

By theory, you have gained some knowledge about Monads. The hard part about Monads is, how you implement them to solve your problem. I would say, practice hard; then only you will truely master the concept.

Try to solve as many problems as you can, using monads. When you will be comfortable with aspect oriented programming (which the monads encourage), and easily speak functional language, then you can tell yourself that you have now mastered the concept. Even after that practice hard.

I think you're absolutely right. The theory behind many concepts I find is actually very simple, c pointers being another example. I mean how simple is this?

int x = 15; int *y = &x;

The hard part is using it to solve your problems.

Sigh. A type `m` is a "monad" if a few functions can be written for it with the following signatures (there are some laws too, but just ignore those until you understand the basics):

    return :: a -> m a
    bind :: (a -> m b) -> m a -> m b
That's all it is. What you've described is a particular type for which these functions can be written.

My advice: stop trying to think of particular ways monads can be used. Rather, you need to understand it as embodying a special flavor of embedding values and functions from one space (the space of simple types a, a -> m b) into another (the space of types m a, m a -> m b).

So, bind, apply and map are just ways of lifting different-shaped functions into (m a -> m b):

    map   :: (a -> b)   -> (m a -> m b) -- from Functor
    bind  :: (a -> m b) -> (m a -> m b) -- from Monad
    apply :: m (a -> b) -> (m a -> m b) -- from Applicative
The moment you start trying to understand these with some first-order metaphor, you know you've lost the way! :)

You aren't describing Monads. You are describing a particular Monad.

You can use the same 'monad pattern' for a variety of stuff such as state computations to mimic mutability, asynchronous pipelining, IO (which if i'm not mistaken is pretty similar to the async pipelining), etc.

A 'monad' is just a term for objects that have flatmap(scala)/selectmany(.NET)/bind(Haskell?) and for comprehension/Do notation is just a convenient pattern built into the languages for working with them.

You understand a usage of monads well, ie. using them to handle failing error states. However, in practice they are also used to deal with other side-effecting functionality such as state, IO, etc. If I was you, I'd look up the Monad instances for State, List, and a few others to get a grip on how you can model your own problem solutions using monads.

Thanks for the tips, I've looked into the List monad, but I'm sure there are some useful ones I haven't looked into. Stacking IO Monads seems to be a useful topic. I'm also looking into Warp and Yesod for the req/res Monads.

My teacher told us that a monad is somewhat like a recipe of an action. A set of instructions without a real purpose of return. So you have to create them under different terms than functions. A function is more of a specification with a constant result, ie put in 2 get 4, regardless of state. It is the combined power of monads and functions which grant access to the more interesting features of a functional programming language.

I'm afraid your teacher is either trolling you, or hasn't much understanding of the topic himself... :(

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | DMCA | Apply to YC | Contact