
On 24 June 2010 08:20, Ivan Miljenovic
My rational for a class approach is that rather than having your library spit out a list of values, etc. you let the consumer pick which data type they prefer (if they're going to be just converting your list into a Set, then why not give them a Set to start with?).
That's a bit more interesting, at least to my tastes. In my own work I often use specialised container types: e.g. rather than use a 'safe list' library that avoids certain list ops or wraps them as Maybe's, I prefer using a OneList: data OneList a = One a | Cons a (OneList a) With structures like a OneList their construction is more 'primary' than their manipulation. That's to say clearly when you build a OneList it can't be empty (and you obviously don't want it to be), but as a structure its not conducive to many manipulations, e.g: you can't filter it, as filtering can produce an empty list but the data type can't. Some "algebra" of constructors and destructors would be useful here, to get the filterInto function for example: filterInto :: Consable c => (a -> Bool) -> OneList a -> c a Consable could be the Coll class from "Bulk Types with Class" or probably better, a smaller one with just empty and cons, or even just cons inheriting Monoid. Unfortunately inheriting Monoid puts "legitimacy" on (++) which we know is bad on regular lists, and should discouraged where feasible. Similarly size in the Coll class is bad on regular lists... it goes on until will have single operation type classes for all the collection operations.