Hacker News new | ask | show | jobs
by wyager 4331 days ago
Even the state monad is not actually sequential. It just appears that way conceptually. It can, just like most haskell code, end up being computed in any order (because of laziness and lambda calculus reordering rules).

For the most part, only "special" monads like IO enforce sequential computation.

3 comments

A good example demonstrating this is the "reverse state monad"

http://lukepalmer.wordpress.com/2008/08/10/mindfuck-the-reve...

It sends state updates "back in time" to compute fixed points. The above article shows how you can compute the fibonacci stream using it.

> For the most part, only "special" monads like IO enforce sequential computation.

No, IO doesn't either, because of laziness. If you need a demonstration, then, in the IO monad, open a file (using the functions in System.IO), read the contents (without doing anything else that depends on them), close the file, and then use the file contents.

IO still works in data dependency order.

That behavior can be seen as a perversion of IO's behavior—it's roughly known as Lazy IO and is considered convenient but potentially very dangerous.

The whole cottage industry of streaming monadic operators like enumeratees, pipes, conduits, io-streams, etc takes "fixing" Lazy IO as a major design goal or inspiration.

Lazy IO depends upon using the function `unsafeInterleaveIO` which, as its name suggests, is considered potentially unsafe---and your example demonstrates why!

You are partially correct. All IO operations "start" in sequential order. Only some of them "finish" sequentially (like putStrLn).
State is sequential when it matters

    x <- get
    put y
    z <- get