
On Tue, Dec 23, 2008 at 3:16 PM, Hans van Thiel
Hello All,
I just saw somewhere that one of the purposes of monads is to capture side effects. I understand what a side effect is in C, for example. Say you want to switch the contents of two variables. Then you need a third temporary variable to store an intermediate result. If this is global, then it will be changed by the operation. But what is a side effect in an fp language like Haskell?
Generally speaking, you have no side effects whenever the only result of a function is the return of its outcome, in contrast with those changing something else (like updating a database, a file, the screen output and so on). In Haskell you can't write an effectful function because its scope is limited to the function's local bindings (i.e. its input arguments and any other name locally defined in its definition). If you want something "global" to affect a function's operations you have to pass it, either explicitly (pure functions) or implicitly (monadic actions). Likewise, if you want to persist an effect after a function's execution you have to gather it from the returned value and feed it to any other subsequent function calls. Though, notice that there are exceptions to the above rule (namely unsafePerformIO) but they are kind of tricks.
As a follow up, I understand why an IO action like getLine or getChar is not a function; its results can be different for different calls.
Anything in Haskell is a function: getLine and getChar ARE functions returning actions to be executed in the IO Monad, i.e. at run-time.
But why not have something like getChar c or getLine str? The types of c or str are pretty clear, aren't they?
Because c are not effected by getChar or getLine, as they are outside the scope of the functions. What you are really passing to getChar/getLine is just the content of c and str which goes out of the scope just after the functions have finished executing. Hope this helps. Cristiano