Hacker News new | ask | show | jobs
by lmm 2517 days ago
It needs to be associative. More concretely, if you want to have something like "do notation" that makes sense, so that you can write code like:

    x <- f(a)
    y <- g(b)
    z <- h(c)
for composition, then it needs to be the case that x.flatMap(a => f(a)).flatMap(b => g(b)) is equivalent to x.flatMap(a => f(a).flatMap(b => g(b))). Unfortunately people sometimes implement a flatMap where these are almost, but not quite, equivalent, which leads to very confusing behaviour and subtle bugs.

You also need to be able to "point" a pure value and have the equivalences you'd expect - this often ends up being important as e.g. the base case of a recursive function.

2 comments

If you have a macro then something like "do notation" could be done in a superset of JavaScript, such as something like this:

  const listMonad=(m,f)=>[].concat(...m.map(f));
  const x=listMonad*>{
    let a=yield [1,2,9];
    let b=yield [3,4,5,7];
    return a-b;
  };
Such a code can then be compiled into a ordinary JavaScript code.
Sure! But note I said "initial intuition". return/pure and monad laws can be explained later, once one understands that there's really nothing magical about monads.
Of course there's nothing magic. But I think it's important to grasp the definition as a whole rather than thinking monads are "just" some subset or superset - the full definition of a monad is quite short and every part of it is vital, even if it doesn't seem so to start with.