[Haskell-beginners] How to avoid repeating code
Daniel Fischer
daniel.is.fischer at googlemail.com
Fri May 27 20:00:19 CEST 2011
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
More information about the Beginners
mailing list