Hi Heribert,

Thanks for your feedback!

| at the end of section 2 of http://www.cse.ogi.edu/~mpj/fds.html you
| might want to mention that there is a "standard" work-around whenever a
| type constructor is needed but not available: Introduce a newtype.

Yes, an in fact this idea is mentioned at the end of the constructor
classes paper!).  But it doesn't always work, and, even when it does,
you have to deal with the extra newtype constructors in both types and
terms.  The BitSet example shows when it doesn't work ... your reworking
of that example depended on generalizing the collection type to add an
extra parameter.  But suppose that you didn't want to, or couldn't, make
that generalization.  For example, this might occur (and indeed, has
occurred in some of our experiments at OGI) in programs that package up
somebody else's code to be used via a class.  And if you can't generalize,
then you're stuck.

| For the hash-table example I am pretty sure that the work-around works
| as well, even though I could not figure out your intended
| implementation.

For the hash table example, one possible newtype encoding might be
as follows:

   newtype HTable bucket a = Array Int (bucket a)
   instance (Hashable a, Collects a b)
      => Collects a (HTable b a) where ...

But this has some problems too ... suppose (somewhat bizarrely in
this case perhaps) that you wanted to use a composition of two
collection types to build the bucket type.  The type of the
corresponding collection would be: Array Int (outer (inner a)).
This would work just fine with the functional dependencies version,
but for the constructor classes version you'd have to introduce
yet another newtype and instance:

   newtype Compose f g x = Comp (f (g x))
   instance (Collects a g, Collects (g a) f)
      => Collects a (Comp f g) where ...

And so on ...

| Of course this is just a work-around and does not make functional
| dependencies superfluous.

That's true.  There are plenty of things you can do with dependencies
that you can't do with constructor classes, and vice versa.

I picked the Collects example because I thought it would be something
that would be reasonably familiar, but perhaps it has the danger of
giving people the impression that functional dependencies are an
alternative to constructor classes.  That's unfortunate because they're
really pretty orthogonal.

All the best,
Mark



Reply via email to