Case

From HaskellWiki
Revision as of 15:01, 13 October 2006 by Lemming (talk | contribs) (moved from Hawiki)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Can I have a {{{case}}} where the alternatives contain expressions?


You can make use of some SyntacticSugar of Haskell, namely of ["Guards"].

cond1     -> ex1
            

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: {{{#!syntax 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 {{{#!syntax haskell 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.


If you don't like the parentheses for the pairs, you can also define {{{#!syntax haskell 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]

}}}