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
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

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]

}}}