in Programming, Haskell

There are a number of errors made in putative Monad tutorials in languages other than Haskell. Any implementation of monadic computations should be able to implement the equivalent of the following in Haskell:

minimal :: Bool -> [(Int, String)] minimal b = do x <- if b then [1, 2] else [3, 4] if x `mod` 2 == 0 then do y <- ["a", "b"] return (x, y) else do y <- ["y", "z"] return (x, y)

This should yield the local equivalent of:

Prelude> minimal True [(1,"y"),(1,"z"),(2,"a"),(2,"b")] Prelude> minimal False [(3,"y"),(3,"z"),(4,"a"),(4,"b")]

At the risk of being offensive, you, ahhh... really ought to understand *why* that's the result too, without too much effort... or you really shouldn't be writing a Monad tutorial. *Ahem.*

In particular:

- Many putative monadic computation solutions only work with a "container" that contains zero or one elements, and therefore do not work on lists.
`>>=`is allowed to call its second argument (`a -> m b`) an*arbitrary*number of times. It may be once, it may be dozens, it may be none. If you can't do that, you don't have a monadic computation. - A monadic computation has the ability to examine the intermediate results of the computation, and make decisions, as shown by the if statement. If you can't do that, you don't have a monadic computation.
- In statically-typed languages, the type of the inner value is not fixed at the beginning. It's
`a -> m b`, not`a -> m a`, which is quite different. Note how`x`and`y`are of different types. - The monadic computation builds up a namespace as it goes along; note we determine
`x`, then somewhat later use it in the`return`, regardless of which branch we go down, and in both cases, we do not use it right away. Many putative implementations end up with a pipeline, where each stage can use the previous stage's values, but can not refer back to values before that.

A common misconception is that you can implement this in Javascript or similar languages using "method chaining". I do not believe this is possible; for monadic computations to work in Javascript at all, you *must* be nesting functions within calls to bind within functions within calls to bind... basically, it's impossibly inconvenient to use monadic computations in Javascript, and a number of other languages. A mere implementation of method chaining is not "monadic", and libraries that use method chaining are not "monadic" (unless they really do implement the rest of what it takes to be a monad, but I've so far never seen one).

If you *can* translate the above code correctly, and obtain the correct result, I don't guarantee that you have a proper monadic computation, but if you've got a bind or a join function with the right type signatures, and you can do the above, you're probably at least on the right track. This is the approximately minimal example that a putative implementation of a monadic computation ought to be able to do.