|
|
|
|
|
by jerf
4131 days ago
|
|
Many in the Haskell community don't like the "do" syntax because it obscures the fact that you're actually generating a closure per <-. One of the best ways to really get the utility of the various implementations of the monad interface is simply to notice that the typeclass permits an implementation to call the resulting closure as many or as few times at is chooses. The way the "Maybe" implementation of the Monad interface "short-circuits" a computation is that when it encounters a "Nothing", it chooses to call the closure zero times and simply return "Nothing" back up the stack. The way the standard "List" implementation of the Monad implements its cartesian closure behavior is that it takes the closure and calls it once on each element of the list. The "do" notation is superficially easier to read, but it obscures the underlying mechanics. More complexly, the STM implementation for monad also uses it for backtracking; should something fail it can simply roll back all the function calls it has made and restart. It's not magic, it's a huge, huge pile of closures that the implementing type can use to do all sorts of things. This is also one of the major reasons why good implementations of the monad typeclass in other languages often end up very painful to use; without some sort of friendly syntax that makes it incredibly easy to generate a new closure, you get a lot of "line noise" as you keep typing function (...) { ... function (...) { ... function (...) { ... function (...) {... I'm still in the "I use it" camp personally, but I am sympathetic to the idea that you should start by manually writing out the bind calls on manually-written closures, and only go to the "do" syntax when you understand it thoroughly. Oh, and to set your mind at ease: }}}}. |
|
This backtracking is different since it permits different backtracking points. It is possible to implement a more "civilized" version of the STM semantics this way, with more respect for IO actions.