[Haskell] Per-type function namespaces (was: Data.Set whishes)

Brandon Michael Moore brandon at its.caltech.edu
Thu Feb 26 21:48:40 EST 2004


On Fri, 27 Feb 2004 ozone at algorithm.com.au wrote:

> On 27/02/2004, at 1:13 PM, oleg at pobox.com wrote:
>
> 1) now I have to manually declare a class definition for every single
> function, and I have to declare it in advance before any module defines
> that function (most serious problem; see below),
>
> 2) I then have to declare instances of that type class for every
> function I define,
>
> 3) the type signature for phase reveals no clues about how to use that
> function.

Declaring a type class instance is really no problem. You just need to
write an "instance Class (Type)" instead of "function :: Type" on the line
before the function declaration. The type on "phase" itself wouldn't
provide much information, but the list of instances in each module defines
would be informative. Something like :info wouldn't be much help without
modification.

> So unfortunately, this is hardly a scalable solution.  The entire
> reason I came up with the idea is because if we use type classes to
> implement this sort of overloading, we have to know every single
> possible function that any module author will ever create, and declare
> classes for those functions in advance.  This is fine if you're
> declaring truly polymorphic functions which are designed from the start
> to be totally general, but it is not designed for functions which may
> do vastly different things and may contain totally different type
> signatures, but share the same name because that would be a sensible
> thing to do.  (e.g. the phase function mentioned above.)

In the paper "Object-Oriented Style Overloading for Haskell", Mark Shields
and Simon Peyton-Jones. One of the things they propose is adding method
constraints to the type system which (as far as I can tell) basically
amounts to generating a type class for each funtion name, and letting
you write constraints like (foo :: Int -> Int) on your function.

They would set up the type classes like "class Has_foo a where foo :: a",
which can causes problems if your argument and return value are
polymorphic under a class constraint rather than concrete types. Making
the method classes implicitly closed would probably help here. (closed
classes are another suggestion). While making that closed world assumption
it would probably be nice if it only selected between the versions of the
function that were actually in scope at the moment (so these would act
kind of like methods that overload if you import several of them, rather
than conflicting like normal).

As long as we are integrating these special type classes into the language
we can make sure things like error messages and ghci give decent
information, maybe listing all the different types the function is
imported at, and where each version is defined.

> With the per-type namespace separation I'm advocating, you do not need
> to know and declare in advance that each function "will be" overloaded,
> you simply write a FiniteMap.add function and a Set.add function, and
> you get a simpler form of namespace separation (or overloading) based
> on the first parameter that's passed to it.  It is a solution which is
> more _flexible_ than requiring type class definitions, and it is better
> than having hungarian notation for functions.  In fact, I think that,
> right now, if we replaced the current namespace separation offered by
> the hierarchical module system, and instead only had this sort of
> per-type namespace separation, things would still be better!

How much of the structure of the first paramater would you look at? Could
you an implementation for pairs that depended on the actual types in the
pair? I think you should try to take advantage of the existing type class
machinery as much as possible here, even if what you want are not exactly
(standard) type classes.

> I realise my idea isn't very general in that it only allows this
> namespace lookup/overloading based on the type of a single argument
> parameter, and I think it would be possible with a bit more thinking to
> generalise it to work based on multiple arguments (e.g. via
> argument-dependent lookup, or whatnot).  But even in its current form,
> I honestly think it offers far more flexibility and would lead to
> cleaner APIs than is currently possible.

Read the paper and see if you think something like that might be useful.
In any case, I think there's a decent chance that something useful for
this would also be useful for building interfaces to object-oriented
libraries, and vicea versa. I think there's probably something that covers
both cases nicely and uniformly.

Brandon

> --
> % Andre Pang : trust.in.love.to.save
> _______________________________________________
> Haskell mailing list
> Haskell at haskell.org
> http://www.haskell.org/mailman/listinfo/haskell
>
>



More information about the Haskell mailing list