|
> It seems like those with functional programming experience either already understand monads or grasp it quickly. That's probably survivor-bias (amongst Haskellers, at least); ie. those who haven't grasped it yet probably won't class themselves as Haskellers. > Would it be better to use Python or Javascript which more people understand but still has that functional flair? The problem with using such languages is that they're always dealing with concrete values; in particular they have no concept of interfaces (like Java) or typeclasses (like Haskell). It's certainly possible to use monads in such languages, but it's often hard to justify their use, since there are always less-complex ways to implement particular examples, and without interfaces it's hard to relate the examples together. For example, here are a bunch of monad implementations ("return" and "bind", AKA ">>=") in Javascript, but it's not at all obvious why they are related to each other: function state_return(val) {
return [null, val];
}
function state_bind(x, f) {
return f(x[0], x[1]);
}
function maybe_return(val) {
return [val];
}
function maybe_bind(x, f) {
return (x.length > 0)? f(x[0])
: [];
}
function list_return(val) {
return [val];
}
function list_bind(x, f) {
return [].concat.apply([], x.map(f));
}
function read_return(val) {
return function(x) { return val; };
}
function read_bind(x, f) {
return function(arg) {
f(x(arg))(arg);
};
}
The problem is that in Javascript, the implementation details are there for all to see. I might want to give you a string which depends on some integer state, but you can always see that it's actually implemented as an array containing an int and a string. You're also free to mess up that array by adding or removing elements from it, which are perfectly valid array operations, but which makes no sense for "stateful values".Interfaces like monads are useful when we're not free to mess around with the implementation; when we must perform all actions through a limited API. When we're dealing with such concerns every day ("I'd like to allow X, but don't want anyone to abuse it and end up with Y") then monads (and functors and applicatives, which they're based on) are really useful as standard APIs for allowing arbitrary operations to be performed, under the control of the API. The only example above that even comes close to this idea is the "reader" monad, implemented with `read_return` and `read_bind`. This is because values in the reader monad lets us manipulate the return values of functions, and even in dynamic languages a first-class function is pretty much a black box, so there's little we can do to mess it up. |