|
|
|
|
|
by _0w8t
2824 days ago
|
|
Look at any do block in Haskel, PureScript, Idris etc. It is the imperative code. The individual effects are typed and separated, but it is still the code that depends on implicit state with all its drawbacks. Then look at Elm code. Elm does not have any imperative hatches. The monad that runs everything is at the very top level (“shell” as the article calls it) and hidden. As such Elm code is forced to use functional decomposition resulting in very easy to follow, refactor and maintain designs. |
|
If you're working with a free monad, or if you don't specify IO (just some of the generic IO like typeclasses like say MonadError), you can still choose your own interpreter for the monad and "program" the semicolon. Which means you get back all the benefits of testability etc.
To get a similar effect in an imperative language, you would use e.g. coroutines and `yield` every side effect to the execution engine. The engine will take the action "specs" (probably a data structure describing the action to perform, e.g. set some value in memory) and decide what to do with them, and you can swap the real engine with a test/mock engine in your tests.