2009/1/16 Peter Verswyvelen <bugf...@gmail.com> > [...] > > After a while you decide that you need to change the Bla data type, maybe > give Dog more fields, maybe completely redesign it, maybe not exposing it, > but you want to keep existing code backwards compatible. With F# you can > write Active Patterns for the old Dog and Cat constructors, so all existing > code remains compatible. At least that is the way I understand it, but I > have not actually worked yet with Active Patterns, will do so soon :) > > You get something similar with the record syntax (though, probably still not quite as powerful as the active patterns):
> data Blah = Dog { dogA :: Int } > | Cat { catA :: Int } > f :: Blah -> Int > f (Dog {dogA = a}) = a > f (Cat {catA = a}) = a f (Dog { dogA = 1}) ==> 1 f (Cat { catA = 1}) ==> 1 If we add more fields: > 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 [1]: http://www.haskell.org/ghc/docs/latest/html/users_guide/syntax-extns.html
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe