# Difference between revisions of "Case"

(sections) |
|||

Line 62: | Line 62: | ||

=== Using syntactic sugar === |
=== Using syntactic sugar === |
||

+ | |||

+ | ==== Guards ==== |
||

You can make use of some [[syntactic sugar]] of Haskell, namely of [[guard]]s. |
You can make use of some [[syntactic sugar]] of Haskell, namely of [[guard]]s. |
||

Line 75: | Line 77: | ||

Alternatively, one could simply factor out a function(/value) and use guards in the argument patterns. |
Alternatively, one could simply factor out a function(/value) and use guards in the argument patterns. |
||

− | === |
+ | ==== List comprehensions ==== |

An alternative sugarful approach is to use [[list comprehension]]s. |
An alternative sugarful approach is to use [[list comprehension]]s. |

## Revision as of 20:40, 3 November 2008

## Contents

## Question

Can I have a `case`

where the alternatives contain expressions?

## Answer

There are several approaches to this problem.

### Using functions

We can do this nicely with a function implemented in Haskell:

```
select :: a -> [(Bool, a)] -> a
select def = maybe def snd . List.find fst
select exDefault
[(cond1, ex1),
(cond2, ex2),
(cond3, ex3)]
```

Unfortunately this function is not in the Prelude.

Alternative implementations are

```
select' def = fromMaybe def . lookup True
{- a purely functional implementation of if-then-else -}
if' :: Bool -> a -> a -> a
if' True x _ = x
if' False _ y = y
select'' = foldr (uncurry if')
```

The implementation of `select''`

makes clear that `select`

can be considered as nested `if`

s.
The functional `if'`

is also useful in connection with `zipWith3`

since `zipWith3 if'`

merges two lists according to a list of conditions.
See if-then-else.

Alternatively you can unroll `foldr`

and write

```
if' cond1 ex1 $
if' cond2 ex2 $
if' cond3 ex3 $
exDefault
```

If you use `if'`

in infix form,
you may call it `?`

like in C,
then because of partial application it will work nicely together with '$' for the else clause.

```
infixl 1 ?
(?) :: Bool -> a -> a -> a
(?) = if'
cond1 ? ex1 $
cond2 ? ex2 $
cond3 ? ex3 $
exDefault
```

### Using syntactic sugar

#### Guards

You can make use of some syntactic sugar of Haskell, namely of guards.

```
case () of _
| cond1 -> ex1
| cond2 -> ex2
| cond3 -> ex3
| otherwise -> exDefault
```

Alternatively, one could simply factor out a function(/value) and use guards in the argument patterns.

#### List comprehensions

An alternative sugarful approach is to use list comprehensions.

```
head $
[ ex1 | cond1 ] ++
[ ex2 | cond2 ] ++
[ ex3 | cond3 ] ++
[ exDefault ]
```