
On Friday 27 May 2011 19:23:54, Federico Mastellone wrote:
Now I have a new problem, it's getting really difficult to program generically and to create highly parameterized libraries.
Yes.
So far so good with type families, but when I want to return a generic Set for the getValues function and provide a default implementation for getValuesCount function I don't know how to do it, I don't even know if it is possible.
You can't return a generic Set in getValues (unless you jump through a lot of hoops, IntMultiMap has IntSets, so you'd have to transform those to Sets, ... yuck) and default implementations wouldn't be possible [or at least rather horrible], but
newtype MultiMap k v = MultiMap (Map.Map k (Set.Set v))
newtype IntMultiMap = IntMultiMap (IntMap.IntMap IntSet.IntSet)
class (Ord (Elem c)) => Collection c where type Elem c emtpy :: c singleton :: Elem c -> c size :: c -> Int null :: c -> Bool member :: Elem c -> c -> Bool ...
class MultiMapClass m where
class (Collection (Coll m)) => MultiMapClass m where
type Key m type Value m
type Coll m
empty :: m addValue :: Key m -> Value m -> m -> m getValues :: Key m -> m -> Set (Value m)
getValues :: Key m -> m -> Coll m
getValueCount :: Key m -> m -> Int getValueCount k m = Set.size $ getValues k m
getValueCount k m = size (getValues k m) Should work or be possible to make working. But things get more complicated the more generic functionality you want to add. It would probably be possible to get a more elegant implementation if you designed the library to use a class-based interface from the ground up (take a look at the edison library [EdisonAPI and EdisonCore on hackage] for an idea of how to structure the classes - edison is old, it was created long before type families or functional dependencies were available, I don't know what new stuff was incorporated into it, I suspect not too much, so you could probably improve the design with the new powerful tools at your hands, but as a source of inspiration, it should still serve well). The problem is that, as a rule of thumb, class based genericity costs performance. And the point of the containers package was to provide performant data structures, the genericity was wilfully forsaken. So, perhaps writing a generic envelope for the containers types might not be the best option. It could be better to start from a clean sheet. [disclaimer: I have not thought about how to do that, nor looked at the API or implementation from that point of view, so my hunch may be quite wrong.] Cheers, Daniel