[Haskell-beginners] How to avoid repeating code

Federico Mastellone fmaste at gmail.com
Mon May 30 21:44:32 CEST 2011


Thanks again Daniel!!

I've been looking at the Edison package, it has a big class
hierarchy without default implementations using functional dependencies and
I found tidier doing something similar with associated types.

Writing default implementations continues to be troublesome.

Here is an example adding an elems function to the Collection class
 elems :: c -> [Elem c]
I can't write on the MultiMapClass class a default implementation
for getValueList like this
 getValueList :: Key m -> m -> [Value m]
 getValueList k m = elems $ getValues k m
because elems returns
 [Elem (Coll m)]
so I have to write
 getValueList :: Key m -> m -> [Elem (Coll m)]
and it doesn't matter that this means the same for the implementations I
have
 Elem (Set.Set a) ~ Value (MultiMap k v)
and
 Elem IntSet.IntSet ~ Value IntMultiMap

Now when using classes like this you need to need to think twice when
coding! Typing becomes much more complicated.

I don't know if I am too object oriented or is the lack of IDEs but reusing
code, grouping together code with similarities and managing many modules is
not easy with Haskell. Things that I found essential to write large
programs. I'm starting to think that the easiest way of writing generic and
reusable code with Haskell is writing a Haskell parser and code generator in
Haskell.

On Fri, May 27, 2011 at 3:00 PM, Daniel Fischer <
daniel.is.fischer at googlemail.com> wrote:

> 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
>
>


-- 
Federico Mastellone
Computer Science Engineer - ITBA

".. there are two ways of constructing a software design: One way is to make
it so simple that there are obviously no deficiencies, and the other way is
to make it so complicated that there are no obvious deficiencies. The first
method is far more difficult."

Tony Hoare, 1980 ACM Turing Award Lecture.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/beginners/attachments/20110530/6804f439/attachment.htm>


More information about the Beginners mailing list