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

ozone at algorithm.com.au ozone at algorithm.com.au
Fri Feb 27 02:53:50 EST 2004


I've had an idea stewing in my head to do with per-type function 
namespaces, that the current module namespace discussion reminded me 
about.  The problem is that there is a limited namespace for functions, 
so that if you define a new data type, it is unwise to call functions 
which work on that data type a very generic name such as 'add'.  An 
example of this is Data.FiniteMap and Data.Set: both data types define 
a function to add things to their respective data types.

addToFM :: Ord key => FiniteMap key elt -> key -> elt -> FiniteMap key 
elt
addToSet :: Ord a => Set a -> a -> Set a

So at the moment, many Haskellers will append the type name to the 
function to indicate that it only works on that particular data type.  
In this respect, Haskell is at a disadvantage vs most object-oriented 
languages, because in them, you can write "x.add", and the type system 
will perform "object-oriented polymorphism" for you and call the 
correct add method, no matter if x is a FiniteMap or a Set.  Writing 
"addToFM fm ..." or "addToSet set ..." is surely a lot more 
inconvenient than writing "fm.add" or "set.add", no?

The idea that I've been throwing around is to be able to define a 
separate namespace for each type; a function can either belong in a 
"global" (default) namespace, or belong in a particular type's 
namespace.  So, in the above example, instead of writing "addToFM fm 
...", we could instead associate an 'add' function with the FiniteMap 
type, so we could write "fm.add ..." instead.  Provided that fm's type 
is monomorphic, it should be possible to call the 'correct' add 
function; if we defined another 'add' function that's associated with 
the Set type, that will only get called if the 'x' in "x.add" is of 
type :: Set.  So, like OO languages which inherently give separate 
namespaces to their different objects, here we give separate namespaces 
to different (monomorphic) types.  In this case, if one simply writes 
"add" instead of "x.add", the compiler throws an error, because there 
is no 'add' function defined in the default namespace; add is only 
defined when a programmer writes "x.add" where x :: FiniteMap or x :: 
Set[1].

There are a number of means by which the x in x.add can be communicated 
to the actual function: it's similar to the hidden 'self' or 'this' 
variable that's present when you invoke a method on an object in OO.  
Perhaps x is passed to the function as its first parameter, or maybe it 
could be its last parameter, or even an arbitrary parameter (where the 
parameter it's passed as could be defined in the type signature of the 
function).  Perhaps 'self' or 'this' could be an implicit parameter.  
Any one of them will work just fine, I think.

However, this scheme is only for functions which have such a 'primary' 
data type to be associated with, such as FiniteMap or Set.  For 
functions which are truly polymorphic (such as ==), you still leave 
them in the default namespace.  Perhaps it's sensible to even make it a 
requirement that functions in the default namespace must be 
polymorphic: if they are monomorphic, they are associated with 
operating on a specific data type, so they should belong in a 
type-specific namespace.  You then still guarantee that such 
commonly-used polymorphic functions cannot be 'hijacked' to have stupid 
type signatures; i.e. == is always guaranteed to be :: Eq a -> a -> 
Bool.

Anyhow, feedback is more than welcome; I would certainly welcome this 
addition if it's feasible.  It feels inferior to be typing in 'addToFM 
foo' all the time when our OO brethren type the simpler and more 
succinct 'foo.add', especially given that Haskell's type system is far 
more powerful!

1. I haven't thought hard enough about whether it would be possible to 
have the same function name in both the 'default' namespace as well as 
in per-type namespaces, but my gut feeling says it should be OK.


-- 
% Andre Pang : trust.in.love.to.save


More information about the Haskell mailing list