
Ask HN: What is a monad? - Azuldolphin
I'd like to start digging into functional programming beyond what is available in C# and Javascript, and began by reading a little about Haskell. There are a lot of mentions about something called Monads, which are part of category theory.<p>Can someone provide an explanation that would make sense to an experienced developer in the OOP world?
======
yummyfajitas
It's a design pattern for encapsulation, with similar goals to OO but
different methods. Rather than telling you what a monad is, I'll just tell you
the goal.

OO is designed to hide the dangerous parts of the world from you. The
dangerous parts of the world (or at least _some_ dangerous parts of the world)
are encapsulated inside little black boxes with well defined interaction
points. If you interact only through those little boxes, you should be safe.
For instance, a logger object gives you 1 methods: writeLog (I'll ignore
logging levels). The details of actually writing logs are not your business,
and you (in principle) don't need to worry about them.

Monads are stricter. A monad puts you into a box and only gives you a few
interaction points with the outside world. You can do whatever you want in a
monad, but you are never allowed to leave the box. Inside the logger box, you
are permitted only pure functions (functions with no side effects) and
writeLog.

So basically, in an OO world, code using a logger might call
os.unlink("/var/log/myprogram.log"). This would interact in a harmful way with
your logging mechanisms. In a monadic world, from _inside_ the logging monad,
you are not given access to os.unlink.

Thus, f: a -> Loggable b in the monadic world (where Loggable b is an b living
inside the box) is safer than f: (Logger, a) -> b in the OO world.

~~~
StavrosK
So, a sort of sandbox function?

~~~
thesz
Yes.

But, more like sandbox type.

~~~
StavrosK
Hmm, I see. Does it also execute code, like a sort of exception handler, or is
it just for limiting/allowing access to scope?

~~~
chc
A monad is a type that has certain associated functions — to wrap values in
the monad and do calculations on what's inside. The type itself obviously
cannot execute code, but the associated functions obviously do. Monads can be
used to implement exceptions.

As an example, lists are monads. The operator for doing calculations with the
value in a monad is >>= (pronounced "bind"). To double every item in an array,
you could do:

    
    
        [1, 2, 3] >>= \n -> [n * 2]
    

(The syntax "\n -> [n _2]" defines a function that takes one argument, n, and
returns a list containing n_ 2.)

There's clearly work going on behind the scenes to pass each value in the list
to the associated function as "n", and then combine all the resulting [n * 2]
lists into one big list of the same type as the original. But that's all
transparent to the programmer. He only sees the interface that the monad
offers.

~~~
StavrosK
Hmm, I see. The problem with my understanding it is that people are describing
its properties and I have to build the mental model from them.

Are Python list comprehensions monads?

~~~
chc
Well, it's the type itself that's a monad. So the question would be, are
Python lists monads thanks to list comprehensions? And the answer is: Kind of.
The idea of a monad in functional programming is that it's a generic type that
can have a lot of different implementations.

The two operations that must be defined for a monad are:

• Return: You pass any value and it returns a monad encapsulating that value

• Bind: You pass a function taking an argument of the type wrapped by the
monad and returning another value wrapped in the monad, and it returns a value
of the monad

With these two operations, you can accomplish a surprising range of tasks.
Python borrowed list comprehensions from Haskell, where they _are_ based on
monads — but in Python, they're kind of orphaned from their monadic roots.

~~~
StavrosK
This makes it much clearer, thanks. Those two operations weren't mentioned
anywhere else that I saw, and they are very helpful in explaining what monads
are.

------
wnoise
What, no one is giving the standard answer of "a monad is a monoid in the
category of endofunctors?"

A category is something like a set, but combining the objects with allowed
operations. (How very OOP!) The available functions are first-class citizens
(called arrows). The objects are the domains and ranges of the arrows, and
their internal structures are not exposed. Arrow composition is associative
when it is defined. (You can only compose an arrow if the range of one is the
domain of the next.)

A functor is just a (natural) function on categories mapping both objects and
arrows in a compatible way. Endofunctors map to the same category.

As each object in this category of endofunctors is a function we want to
compose, we have to be given a way to do that. This is what that the monoid
here does -- it's a way to describe the allowed ways of combining natural
transformations, including any systematic tweaks to be done during the
combination.

(The classical definition of a monoid is just a set with an associative binary
operation with an identity.)

~~~
omaranto
The paragraph starting "As each object in this category..." made no sense to
me. I can explain the what a monoid in the category of endofunctors is, how it
relates to a Haskell monad and maybe you can explain what you meant.

OK, a monoid in the category of endofunctors is an endofunctor F together with
a natural transformation (the multiplication of the monoid) from F composed
with F to F, and another natural transformation from id to F (called the
unit). In Haskell F is the type constructor of the monad, the unit is called
return and the multiplication is usually called join (and in the case of the
list monad is also known as concat).

(Note that the definition of monoid needed here is not that of a set with
associative binary operation, but the more general "monoid object in a
monoidal category". Instead of a set S and a multiplication S x S->S, where x
denotes cartesian product, we want a functor F and a multiplication F o F->F
where o denotes composition. This is an instance of the general sort of monoid
since the category of endofunctors is monoidal with respect to composition.)

~~~
wnoise
I didn't want to give the full categorical definition in terms of what a
monoidal category allows, because I don't think that adds much, but I suppose
I flubbed making it simpler. I just wanted to make the point that the monoidal
portion determines how the composition occurs -- a given type constructor can
be a monad multiple ways.

------
g__
DON'T start functional programming with monads. Familiarize with currying,
pattern matching, how to create data types in Haskell, using recursion instead
of loops, higher order functions, list comprehensions, type classes,
polymorphism in Haskell (different than subtyping in OOP). Ignore monads for a
while. To understand monads you must have a good grip of those concepts. You
can start with <http://learnyouahaskell.com/chapters>.

You'll see Haskell tutorials delay telling about the concept. There's a
reason.

For a bird's eye of monads you can check this:
[http://www.reddit.com/r/programming/comments/64th1/monads_in...](http://www.reddit.com/r/programming/comments/64th1/monads_in_python_in_production_code_you_can_and/c02u9mb)

If you are ready, read and do exercises in
<http://blog.sigfpe.com/2007/04/trivial-monad.html> and then
[http://blog.sigfpe.com/2006/08/you-could-have-invented-
monad...](http://blog.sigfpe.com/2006/08/you-could-have-invented-monads-
and.html).

------
pwpwp
A cheap and unexciting trick for passing a value through a couple of
functions. (Monads _are_ cool, but it's important to understand that there's
nothing, nuttin', whatsoever fancy about them, so I like to call them a "cheap
trick".)

This is a good intro:
[http://homepages.inf.ed.ac.uk/wadler/papers/marktoberdorf/ba...](http://homepages.inf.ed.ac.uk/wadler/papers/marktoberdorf/baastad.pdf)

Be sure to mentally replace "monad" with "warm fuzzy thing" when reading it
and it should make sense.

~~~
thesz
Actually, the effects of that trick are nothing less than exciting.

For example, that trick allows you to pass information from future (one of
Wadler examples).

------
samstokes
Monads are _red herrings_ , if what you're interested in is getting started
with functional programming (or even Haskell specifically). It's an
unfortunate flaw in the Haskell literature that makes it seem like you have to
grok monads to learn Haskell; you don't.

Monads _enable syntactic sugar_. If you're getting started with Haskell,
you'll notice that when you write code that does I/O, you use a weird
imperative-looking syntax ("do notation") that looks different to the normal
functional style:

    
    
        main :: IO ()
        main = do
          putStrLn "Please enter your name"
          name <- getLine
          putStrLn ("Hello " ++ name ++ "!")
    

'putStrLn "Hello"' doesn't actually print anything; it returns an IO value
that, when interpreted by the Haskell runtime, prints something: that
interpretation takes place when 'main' is run. The do notation is syntactic
sugar for creating a sort of compound IO value that interprets as a bunch of
actions rather than just one. The reason you can use do notation for IO but
not for (all) other Haskell code is that IO values are monadic (which is
another and possibly more useful way of saying "IO is a monad"): that just
means that they behave in a certain way when combined (to produce that
compound value) and obey certain laws to make the do notation well behaved.

Monads are _a design pattern_ to abstract away repetitive functional code. For
example, if you write a lot of pure-functional code you sometimes end up
having to pass around a 'state' parameter. If a function reads or writes from
the state, then any function that calls it has to pass in the state, and so
on. This leads to a lot of functions with an extra state parameter, many of
which don't even care about the state except to pass it down the call tree. An
improvement would be to write a higher-order function which took a function
which didn't care about state and wrapped it to produce one that just passed
the state through. The State monad encapsulates this wrapping and lets you
clean up the rest of your code.

Monads are _what's between the lines_ of an imperative program. Bourne shell
scripts have the default error-handling rule that they ignore failing commands
unless it's the last one executed, or put another way, they run in a monad
that ignores errors:

    
    
        cat nonexistent.txt   # prints an error message
        echo Done.            # still executes, prints "Done."
        # script returns success
    

But you can tell it to run instead in a monad which stops after the first
error:

    
    
        set -e                # change the monad, i.e. the error-handling rule
        cat nonexistent.txt   # prints an error message
        echo Done.            # never runs
        # script returns failure
    

Old-school Visual Basic has the opposite default, but you can make it behave
like a shell script with "ON ERROR RESUME NEXT". Yes, VB had monads.

Monads are _a specific example of higher-kinded polymorphism_ , which is a
very powerful and useful concept that's starting to enter the programming
mainstream (examples are template concepts in C++ and LINQ in C# and .NET).
Parametric polymorphism (List<String> in Java and C#, etc) means you don't
have to write a 'reverse' function that works on lists of strings, and another
'reverse' function for lists of ints, etc; you can just write a generic
reverse function that works on lists of any kind, because it doesn't need to
know the details of the contained type, just how to iterate over a list.
However, if you want to reverse an _array_ , you still have to write a new
'reverse'. If your language supports higher-kinded polymorphism, you can write
a generic reverse function that works on any kind of container, because all it
needs to know is that the container has some well-behaved method of iteration.

(The LINQ example is a bit more subtle, because C# _doesn't_ support higher-
kinded polymorphism, but LINQ is a hard-coded exception to that rule. The cool
LINQ syntax works for any type which provides certain operations and behaves
in a certain way - which just happen to coincide with the requirements for the
type to be monadic.)

~~~
joe_the_user
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"...

~~~
mrpsbrk
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.

------
okmjuhb
Let's say you wanted to implement I/O in a language without side effects. You
could put all your interactions with the world in a special "World" object.
Every time you called world.putString("foo"), you'd get back a new world
object that represents the state of the world with "foo" having been written
out.

So the code (quoting from samstoke's hello world):

    
    
        main :: IO ()
        main = do
          putStrLn "Please enter your name"
          name <- getLine
          putStrLn ("Hello " ++ name ++ "!")
    

would get translated to:

    
    
        main :: World -> World
        main world = let newWorld = putStrLn world "Please enter your name" in
                       let (newerWorld, name) = getLine newWorld in
                         let newestWorld = putStrLn newerWorld ("Hello " ++ name ++ "!") in
                           newestWorld
    

Note that this makes the order of operations explicit, and that no World needs
to be modified. Note also that now main has to take and return one of these
World objects, so that a World needs to be threaded through all computations
that will interact with the World (just like IO actions can only be executed
from within other IO actions).

A monad lets you thread implicit state through a computation.

------
DanielRibeiro
Monads are (quote) elephants: [http://james-iry.blogspot.com/2007/10/monads-
are-elephants-p...](http://james-iry.blogspot.com/2007/10/monads-are-
elephants-part-3.html)

Monads can be implemented in OO languages, like ruby:
[http://moonbase.rydia.net/mental/writings/programming/monads...](http://moonbase.rydia.net/mental/writings/programming/monads-
in-ruby/00introduction.html)

Tony Morris, on of the authors scalaz (which implements monads, among other
things, in scala ): [http://projects.tmorris.net/public/what-does-monad-
mean/arti...](http://projects.tmorris.net/public/what-does-monad-
mean/artifacts/1.0/chunk-html/index.html)

A one that was considered a very good explanation on the topic:
[http://blog.sigfpe.com/2006/08/you-could-have-invented-
monad...](http://blog.sigfpe.com/2006/08/you-could-have-invented-monads-
and.html)

------
thesz
My friend told me recently that he invented monads in Javascript:

    
    
      result = monadicObj
             .action1(arg)
             .action2(arg2);
    

I told him that he needs variable binding operations for fully fledged monads:

    
    
      result = monadicObj
             . x <- action(arg)
             . y <- action2(x,arg2)
             . action3(x,y,arg3)
             . return (x+y);
    

Otherwise, his invention is much more like Applicative, because we cannot pass
values between actions.

So here it is: monads are just objects with overloaded and extended "."
operator and with special function "return" that modifies object (in
accordance with object meaning) and returns it's input value unchanged. That
new operator allows us to bind return results if we want so. Overloading of
"." allows us to implement various interesting operations - passing state,
executing optional computations, executing non-deterministic computations,
probabilistic computations, etc.

You incapsulate the meaning of computation inside object, so you can pass it
to some evaluator without that evaluator knowing that you pass him non-
deterministic computation instead of monte-carlo monad or vice-versa.

------
clofresh
jQuery is a monad: <http://news.ycombinator.com/item?id=439116>

------
ChristianMarks
Moggi used monads in category theory to define computations with side effects
in functional programming. The basic insight is that in addition to the values
of various types in functional programming, there are "computations" of
various types. Examples of "computations" would be exceptions or
continuations. Each monad defines for each value type a computation
"containing" that type, and the whole type system of values you started with
can be embedded in a new type system with new computation types.

Monads in category theory are an algebraic device for embedding a category--
usually a cartesian closed category--of types of values into a new category
with types of computations. However, the correspondence between Haskell monads
and category monads are related by a series of adjunctions.

Suppose that C is a cartesian closed category and M:C->C is a monad with
natural transformations e:1->M (the unit) and u:MM->M (the multiplication).

We assume a fixed choice of products and compatible exponentials: for each
type A of C,

    
    
      A x ( ) -| [A -> ( )]
    

Here's the adjunction

    
    
      MA -> [[A->MB] -> MB]
      ---------------------
      MA x [A -> MB] -> MB
      ---------------------
      [MA -> MB] x MA -> MB
      -----------------------
      [A -> MB] -> [MA -> MB]
    

The final map is given by currying, but it can also be motivated as follows if
you think of the exponentials as internal hom sets. If g:A -> MB is in C, so
that g:A->B is in the Kleisli category C^M, then u_{MB}oM(g):MA->MB. We can
write this as the lambda term \lambda x\in A A -> MB.u_{MB} oM x

This lambda term corresponds to composition in the Kleisli category C^M of C,
and belongs to the internal language LL(C), the simply typed lambda calculus
determined by C. Under the Curry-Howard-Lambek correspondence, the lambda term
corresponds to the required map of C.

------
fab13n
It's the operator that allows to chain two statements together. It's written
";" in Pascal, and is often implicit in other languages.

When a language explicitly talks about monads, it's because it lets you
overload that operator, i.e. it let's you give alternative definitions of what
it means to chain statements together.

------
brudgers
Leibniz on Monads:

[http://www.rbjones.com/rbjpub/philos/classics/leibniz/monad....](http://www.rbjones.com/rbjpub/philos/classics/leibniz/monad.htm)

~~~
samstokes
Unfortunately "monad" gets used in a few contexts unrelated to the sense the
OP is asking about. Similarly, the (cancelled) TV series Caprica recently
started using "monad" to mean "monotheist".

~~~
brudgers
On the other hand, it seems that if one is willing to propose a similarity
between one of the cornerstones of rationalism and the misuse of "monad" by a
fictional character on a canceled television series, one might be more open to
seeing more direct lines of intellectual descent from an inventor of the
calculus to functional programming.

The embedded type system of a programmatic monad remains unchanged despite the
monad's combination into higher level structures - a somewhat Leibnizian
characteristic.

------
sbhat7
Slides from functional programming class might clarify things a bit [PDF].

[http://www.it.uu.se/edu/course/homepage/avfunpro/ht10/notes/...](http://www.it.uu.se/edu/course/homepage/avfunpro/ht10/notes/glimming-4up.pdf)

------
lincolnq
I wrote some stuff about monads on HN a while ago that some people found
helpful: <http://news.ycombinator.com/item?id=247446>

------
tel
There are already a number of excellent answers, but I'll try my hand. You
don't know something until you can explain it 3 different ways.

Haskell excels as a functional language because it has excellent piping,
_Monads are just another form of piping_ with particularly great syntactic and
psychological properties. They act as wrappers around a direct type and
setting the return type of a function as a monadic type (such as IO () or
[Int] or Maybe Bool) means that the _primary_ type is () or Int or Bool, but
there's something special being passed along as well.

In practice this saves typing since you don't explicitly pass the special
monadically-hidden information. It also psychologically lets you think of
simple types being wrapped in contexts which have certain properties. Some
contexts can be unwrapped, some cannot. Some contexts can transform into other
contexts directly, some cannot. Learning the behavior of each monad
independently teaches you about these behaviors and then becomes important in
advanced Haskell programming.

When learning, avoid them. Learn how to use IO by rote and ask in IRC about
the confusing type errors that will arise. They usually translate as "you
tried to combine two pipes which don't fit, so that monadic special sauce was
lost". Part of learning Haskell is learning all of the joints and adaptors
which help you to combine types effectively (including monads).

When you have a firm grasp of using compositions and maps and filters, start
with the Maybe monad. Implement it and use all the general monad adaptors on
them. Then learn the basic State monad because it makes the special sauce very
explicit. Learn IO last because it's really a special case and should never be
introduced as a monad.

------
exDM69
I'll have my stab at making a short explanation without code or lots of
technical stuff. So here's some handwaving that may contain mistakes:

Monads are sequential processes, which are combined to make bigger processes.
getLine is a monad, so is putStrLn "hello". You can combine two monads into a
bigger monad using the >>= operator, which would be the "means of combination"
which is extensively discussed in the Structure and Interpretation of Computer
Programs lectures. Simplest monad program I can think of is echo = getLine >>=
putStrLn.

I learned monads by doing simple stuff like guess the number and hangman,
first writing them in the do-notation (syntactic sugar for a mini-imperative
language) and then converting that to concrete notation using >>=.

Monads are not only useful for IO, but also other sequential processes such as
parsing, pretty printing, binary file io and stateful inside but functional
outside algorithms (ST monad).

Disclaimer: this was written by a Haskell newb, recently introduced to the
wonderful world of Monads.

------
Tycho
From my limited understanding garnered by listening to SE Radio, monads are
basically a way for Haskell programs to execute actions (rather than simply
computing values), so that your program can ultimately DO something like write
to a file. As you probably know, the functions aren't supposed to contain any
side effects: you don't want something unexpected to happen when you just want
to calculate a value. It would be like a spreadsheet that printed out a page
every time you entered a certain cell - might make sense in a one-off
situation but in the long run it's just inviting trouble.

So monads allow sequences of actual _actions_ to be packaged together and
given preconditions and then executed in a safe manner (perhaps with an eye to
concurrency). You get to maintain the exquisite purity of functional
programming while still writing software that, you know, gets stuff done
occassionally.

If you were looking for an explanation of the mathematical concept though,
sorry, ain't got a scooby.

------
troutwine
The Wikipedia has a very good treatment:
<http://en.wikipedia.org/wiki/Monad_(functional_programming)>

The monad _is_ the axioms outlined in the article. The applicability of the
monad are the logical consequences of its axioms, but it is _no more_ than its
axioms.

Happy hacking!

------
lallysingh
The short answer is to read chapter 14, probably more than once, before it
makes sense. It took me 2 times: <http://book.realworldhaskell.org/read/>

------
ChadHydro
Monads are a means of guaranteeing program sequentiality and maintaining
state.

