MultiCase

From HaskellWiki
Revision as of 03:47, 30 September 2011 by Drb226 (talk | contribs) (New page: Inspired by http://stackoverflow.com/questions/7603509/haskell-syntax-for-or-in-case-expressions It is proposed that Haskell allow multiple pattern matches in a case statement to map to a...)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Inspired by http://stackoverflow.com/questions/7603509/haskell-syntax-for-or-in-case-expressions

It is proposed that Haskell allow multiple pattern matches in a case statement to map to a single right-hand-side expression.

factorial :: Int -> Int
factorial n = case n of
  0, 1      -> 1
  _ | n < 0 -> undefined
  _         -> n * factorial (pred n)

-- without this suggested extension,
-- the cases of 0 and 1 would have to be handled separately.

If the right-hand-side expression utilizes bound variables from the pattern match, then all grouped pattern matches must bind the same variable.

unEither :: Either a a -> a
unEither eitherVal = case eitherVal of
  Left v, Right v -> v

This is because only one of the pattern matches will occur. Clearly, the RHS cannot draw from multiple differing pattern matches. This would be an error.

-- this would be a scoping error
eitherSum :: Either Int Int -> Int
eitherSum eitherVal case eitherVal of
  Left l, Right r -> l + r

An additional example:

-- modified example from Haskell School of Music
getDur :: Primitive a -> Dur
getDur p = case p of
  ModDur (Tempo r) d           -> d / r
  Note d _, Rest d, ModDur _ d -> d  
-- notice how we don't have to write `-> d` for
-- each of the 3 trivial cases; they all share the same RHS

-- layout rules should also permit
-- splitting the shared matches over multiple lines
getDur' :: Primitive a -> Dur
getDur' p = case p of
  ModDur (Tempo r) d -> d / r
  Note d _,
  Rest d,
  ModDur _ d -> d