# Case

### From HaskellWiki

(Difference between revisions)

(moved from Hawiki) |
(HaskellWiki syntax highlighting) |
||

Line 1: | Line 1: | ||

− | Can I have a | + | Can I have a <hask>case</hask> where the alternatives contain expressions? |

− | You can make use of some SyntacticSugar of Haskell, namely of [ | + | You can make use of some SyntacticSugar of Haskell, namely of [[Guards]]. |

− | + | <haskell> | |

case () of _ | case () of _ | ||

| cond1 -> ex1 | | cond1 -> ex1 | ||

Line 10: | Line 10: | ||

| cond3 -> ex3 | | cond3 -> ex3 | ||

| otherwise -> exDefault | | otherwise -> exDefault | ||

− | + | </haskell> | |

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. | ||

Why sticking to syntactic sugar? We can do it nicely with a function implemented in Haskell: | Why sticking to syntactic sugar? We can do it nicely with a function implemented in Haskell: | ||

− | + | <haskell> | |

select :: a -> [(Bool, a)] -> a | select :: a -> [(Bool, a)] -> a | ||

select def = maybe def snd . List.find fst | select def = maybe def snd . List.find fst | ||

Line 24: | Line 24: | ||

(cond2, ex2), | (cond2, ex2), | ||

(cond3, ex3)] | (cond3, ex3)] | ||

− | + | </haskell> | |

Alternative implementations are | Alternative implementations are | ||

− | + | <haskell> | |

select' def = fromMaybe def . lookup True | select' def = fromMaybe def . lookup True | ||

Line 36: | Line 36: | ||

select'' = foldr (uncurry if') | select'' = foldr (uncurry if') | ||

− | + | </haskell> | |

− | The implementation of | + | The implementation of <hask>select''</hask> makes clear that <hask>select</hask> can be considered as nested <hask>if</hask>s. |

− | The functional | + | The functional <hask>if'</hask> is also useful in connection with <hask>zipWith3</hask> since <hask>zipWith3 if'</hask> merges two lists according to a list of conditions. |

If you don't like the parentheses for the pairs, you can also define | If you don't like the parentheses for the pairs, you can also define | ||

− | + | <haskell> | |

data SelectBranch a = (:->) { | data SelectBranch a = (:->) { | ||

condition :: Bool, | condition :: Bool, | ||

Line 56: | Line 56: | ||

cond2 :-> ex2, | cond2 :-> ex2, | ||

cond3 :-> ex3] | cond3 :-> ex3] | ||

− | + | </haskell> | |

+ | |||

+ | [[Category::Idioms]] |

## Revision as of 15:04, 13 October 2006

Can I have acase

You can make use of some SyntacticSugar 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.

Why sticking to syntactic sugar? We can do it 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)]

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')

select''

select

if

if'

zipWith3

zipWith3 if'

If you don't like the parentheses for the pairs, you can also define

data SelectBranch a = (:->) { condition :: Bool, expression :: a } select :: a -> [SelectBranch a] -> a select def = maybe def expression . List.find condition select exDefault [cond1 :-> ex1, cond2 :-> ex2, cond3 :-> ex3]

[[Category::Idioms]]