
On Feb 21, 2006, at 7:19 AM, Jean-Philippe Bernardy wrote:
As you might know, I've been working on a class-based framework API to accomodate existing collection types, which I intend to be used in place of the concrete modules APIs. It can be found here:
http://hackage.haskell.org/trac/ghc/wiki/CollectionClassFramework
By all means, I'd be interested to have your feedback on my design. I don't mean that there can exist only one, but I guess we can benefit from each other's ideas.
Well, I have to begin with the caveat that I am not a data structures expert, and that the design of Edison is almost entirely due to Chris Okasaki. That said, I can certainly share my opinion. In no particular order: -- Your use of two type parameters to model read-only or unobservable collections is very interesting. I wonder, though, how useful it actually is. I facilitates some interesting possibilities with views, but I can't think of any compelling use cases. I sort of dislike the fact that it can turn certain of the class methods "useless", but maybe the idea just hasn't grown on me yet. -- I like the idea of views generally, and I'm now trying to think if there is a good way to work something like them into Edison. -- The 'isSingleton' method seems unnecessary. Are singleton collections interesting enough to supply a special test for them? -- Your 'lookup' method has a Monad context, which I assume is the 'NotJustMaybe' pattern, but 'front' and 'back' return Maybe. You should probably pick one style and stick to it. -- Qualified infix functions look horrible. I know you say this module should be imported unqualified, but with Prelude clashes people qualify it anyway. I'd suggest you stick to regular prefix functions for your class methods and define the infix functions as the appropriate aliases. That way people importing qualified can still use something reasonable looking. -- In a related thread I've been discussing argument orders. I think I've just about come to the decision that all the Edison API functions will take the collection argument last, including the troublesome 'rcons'. If you take my suggestion to remove infix symbols from your classes, I suggest you also make your right cons and index functions take the collection argument last. However, I'd probably leave the symbols as is, so that, e.g., (|>) = (flip rcons). -- In fact, I like your right and left insert symbols so much, I may adopt them myself. -- You claim that 'union' takes an unspecified element in the case of duplicates, but you also claim it is commutative. You need to specify in what sense you claim commutativity; your collection class doesn't require an Eq or Ord instance, and the claim seems very suspect if you mean up to identity. Similar with intersection. -- Does 'adjust' affect all elements with the given key, or just a single unspecified one? -- 'Indexed' doesn't have any notion of bounds. That seems like a pretty necessary concept. Humm, I see now that MapLike is a subclass of Indexed. Perhaps then you should have 'DenseIndexed' or 'ArrayLike' which has bounds related methods together with the "denseness" property. Overall, I'd say the methods you have carved out seem to be the ones that are most-used, with the notable exception of 'head' and 'tail' for sequences. If you are attempting to go for a fairly minimal set of operations (that's more or less what I read your design goals as saying), then the only method I'd consider adding is a strict fold. People get irritated if they can't, e.g., sum the elements in a collection without building a gajillion unnecessary closures. Rob Dockins Speak softly and drive a Sherman tank. Laugh hard; it's a long way to the bank. -- TMBG