Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Haskell pattern matching symmetric cases

Suppose I have a haskell expression like:

foo (Nothing, Just a) = bar a
foo (Just a, Nothing) = bar a

Is there any haskell syntax to collapse those cases, so I can match either pattern and specify bar a as the response for both? Or is that about as succinct as I can get it?

like image 355
rampion Avatar asked May 11 '11 18:05

rampion


3 Answers

If your code is more complex than your example, you might want to do something like this, using the Alternative instance for Maybe and the PatternGuards extension (part of Haskell2010).

{-# LANGUAGE PatternGuards #-}
import Control.Applicative

foo (x, y) | Just a <- y <|> x = bar a

In case you are not familiar with it, <|> picks the left-most Just if there is one and returns Nothing otherwise, causing the pattern guard to fail.

like image 97
hammar Avatar answered Nov 14 '22 10:11

hammar


That's as succinct as it gets in Haskell. In ML there is a syntax for what you want (by writing multiple patterns, which bind the same variables, next to each other separated by | with the body after the last pattern), but in Haskell there is not.

like image 21
sepp2k Avatar answered Nov 14 '22 12:11

sepp2k


You can use -XViewPatterns, to add arbitrary functions to collapse your two cases into a single pattern. Your pattern is now a function p that yields the thing you want to match:

foo (p -> (Just a, Nothing)) = bar a

much simpler!

We have to define p though, as:

p (Nothing, a@(Just _)) = (a, Nothing)
p a@(Just _,   Nothing) = a
p a                     = a

or however you wish to normalize the data before viewing.


References: The GHC User's Guide chapter on View Patterns

like image 4
Don Stewart Avatar answered Nov 14 '22 12:11

Don Stewart