3 ms·
For a more thorough, probably better written although longer explanation, I say going to http://blog.sigfpe.com/2006/08/you-could-have-invented-monads-and.html
by andolanra 16y ago
For a more thorough, probably better written although longer explanation, I say going to http://blog.sigfpe.com/2006/08/you-could-have-invented-monads-and.html 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.)