> data Blah = Dog { dogA :: Int , dogB :: Int }
> | Cat { catA :: Int , catB :: Int }
> f :: Blah -> Int
> f (Dog {dogA = a}) = a
> f (Cat {catA = a}) = a
f (Dog {dogA = 1, dogB = 2})
==> 1
f (Cat {catA = 1, catB = 2})
==> 1
Note that the definition of 'f' doesn't have to change. If you decide to remove that specific field, then you'll have to refactor f, but the act of adding *more* fields doesn't impact the existing definitions using record pattern matching.
The addition of record disambiguation and wildcards[1] cleans this up a bit more.
> {-# OPTIONS -XRecordWildCards #-}
> data Blah = Dog { a :: Int , b :: Int , c :: Int }
> | Cat { a :: Int , b :: Int }
> dog = Dog {a = 1, b = 2, c = 12}
> cat = Cat {a = 1, b = 2}
> f :: Blah -> Int
> f (Dog {..}) = a
> f (Cat {..}) = a
f dog
==> 1
f cat
==> 1
So, it still might not be able to pull everything off, but it sure covers most of the bases. The cards are especially useful.
I <3 Haskell.
/jve