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

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