[Haskell-cafe] What are side effects in Haskell?
cristiano.paris at gmail.com
Tue Dec 23 10:09:37 EST 2008
On Tue, Dec 23, 2008 at 3:16 PM, Hans van Thiel <hthiel.char at zonnet.nl> wrote:
> 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.
> 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.
More information about the Haskell-Cafe