[Haskell-cafe] Shrinking the Prelude: The "categorical" approach

Brian Hulley brianh at metamilk.com
Wed Dec 20 09:37:56 EST 2006

Imam Tashdid ul Alam wrote:
> hi guys,
> I was just wondering if anyone is interested is a
> "quasi"-project of rewriting the Prelude (only
> shrinking it as measured by the total number of names
> imported, read along...)
> the idea is (just to be substantially different in
> approach) to develop an "alternate history" of
> Haskell.
> take map for example, and fmap, I don't think they
> should be named different (fmap is ugly, not
> suggestive, and conceptually the same).
> mplus could be renamed (++) (they are conceptually the
> same

I suggest that all functions in classes be given actual names and ASCII 
symbolic names could be defined outside the class as an additional 
convenience eg:

    class Monad m => MonadPlus m where
        mzero :: m a
        mplus :: m a -> m a -> m a

    (++) = mplus    -- 'convenience' name

I think people forget that ASCII symbol names which look intuitive to them 
when they are writing a library or paper, can be very confusing for people 
who need to use many libraries (with consequent explosion of obfuscatory 
symbols) in a project, look terrible when qualified, and make code difficult 
to read because of the need to find/remember precedences and associativity. 
(Note that Haddock does *not* supply this info, you need to look at the 
actual source code of the library to find it out.)

> , mzero looks odd, name it empty, or simply zero)

What about (mempty) from Monoid or (empty) from Data.Sequence or 
Control.Applicative? Either these are in some way the same thing as mzero, 
or else they are different in which case either qualified imports would be 
needed everywhere (not necessarily a bad thing) or different names like the 
ones we already have, are needed.

> although I think concat should be replaced by msum (or
> the other way around preferably :) ? msum is a bad
> name) I am somewhat confused by join. concat seems to
> match join's type but I don't think the ideas
> coincide.
> and so on. in particular, we would want:
> * no backwards compatibility. the Prelude as is it, is
> good enough. we are defining a new module.

Starting with a clean slate seems a good idea, especially to get rid of 
lispy names like (cons), (snoc), (null) and replace them with something 
self-explanatory like (pushL), (pushR), (isEmpty).

> * clean categorical hierarchy of type classes
> (category theorists wanted!) promoting uniformity.

This would be great. However it is a question to me whether it is even 
possible to organize everything in a single hierarchy. Eg look at the 
problems with trying to reorganize Num, or standard OOP problems with 
hierarchies in general. Since there are multiple ways of looking at a 
domain, it is likely there will need to be multiple hierarchies which will 
probably not interact so well.

> * cleaner names. foldl1 means nothing. absolutely
> nothing. what's the 1 for?

A while back I suggested using capital letters for suffix to distinguish the 
functionality (fold) from the variant (L == left). Perhaps (foldl1) could be 
renamed (foldLN) ie fold + left + non-empty or (foldLO) for fold + left + 

> * our Prelude only contains typeclasses, datatypes,
> and functions of utmost conceptual (and semantic, such
> as error, undefined and seq) importance, everything
> else goes to other modules. our Prelude is not going
> to be a place for "convenient" declarations.
> * the suffix method of naming (liftM2) is considered
> messy. we would prefer a seperate module (promoting
> qualified import).

In the particular case of *M functions, I quite like the existing naming 
since it's clear that it's a monadic function. However I'd agree that names 
like (newIORef) are an abomination, that should be replaced by (Ref.new).

> this is a fun project. we will not rewrite the
> Prelude, we'll merely rename it. I would suggest the
> name TheOtherPrelude to make our intentions clear. the
> conveniences (like concatMap) goes to
> TheOtherPrelude.Extension. I suggest we do it on the
> wiki. anyone interested just open a page with your
> name of choice. I am not doing it only because there's
> no point doing it if no one's interested.

Good luck with this. For my own project, I re-implemented FingerTree's so I 
could use my preferred naming style (and also as an exercise following the 
excellent tutorial-style FingerTree paper), and wrote some trivial wrappers 
for a few other modules eg Data.IORef, Data.Unique so that I could use 
Ref.new, Unique.new etc.I think it would be quite a big task to refactor the 
entire code base according to a clean hierarchy of type classes, and also a 
task I can't really help with since I'm not familiar enough with category 
theory at present, but certainly it would be a worthwhile endeavour imho,


More information about the Haskell-Cafe mailing list