conditional

Jon Cast jcast@ou.edu
Mon, 22 Jul 2002 20:46:30 -0500


Jonata Goulart <jonatahh@hotmail.com> wrote:
> How do I write a multiple tine conditional in Haskell.

I guess you mean ``line''? :)

> Example: This would work on language like C.

> if (x==1) {
> x = x +1;
> x = x +2;
> x = x +3;
> }

Well, this example has more problems in Haskell than the multi-line if
statement.  I don't think you can implement a C-like `=' in Haskell
98.

In GHC you can give `x' type `IORef Int', and write the first line of
the conditional like this:

do
  xval <- readIORef x
  x `writeIORef` (xval + 1)

Note that, in Haskell, this is two lines.
<aside authority="Jon's tenuous understanding">
In general, the order in which side effects (including reading mutable
variables) occur depends on the evaluation order, and the meaning of
the program depends on the order of side effects.  Haskell expressions
in general contain have very little information about the evaluation
order, and therefore (if they have embedded expressions with side
effects) about the program's behavior.  This is bad, since the
program's behavior is not obvious from the source code.

The solution Haskell adopts, as I understand it, is to supply the `do'
construct to make the order of evaluation explicit.  So, since the C
statement `x = x + 1' contains two side effects, we need to use `do'
to explicitly specify the order of those side effects.
</aside>
This should answer your main question (almost).  You write the body of
a multiple line conditional the same way you write any other multiple
line program:

do
  xval <- readIORef x
  if xval == 1
    then do
      xval <- readIORef x
      x `writeIORef` (xval + 1)
      xval <- readIORef x
      x `writeIORef` (xval + 2)
      xval <- readIORef x
      x `writeIORef` (xval + 3)
    else return ()

Note that, in Haskell, the `if' construct forms and /expression/, not
a statement.  Therefore, you have to provide an `else' clause.

> Thanks.

Jon Cast