I would jump to a bigger, safer and more beautiful prelude at once. And I would most like it to be called
* * *
The good note that there are different classes of use cases has already been given and I think it is essential that we spell these classes out. The simplest is the dichotomy of libraries and applications — I am going to consider it presently. Another note to keep in mind is that the purpose of a prelude is twofold: to enable presence and to advertise absence.
If I am writing a pure library for munching big data:
There is really no point for me in having potentially useful data structures dispersed across many packages. I would rather have all of them at hand. Enable me to use the best tool for the job by default.
containerskind of does the right thing here, and it should be pushed farther.
At the same time, I would rather not have anything to do with IO, Template Haskell and
unsafeCoercein this library, and I would like to be enabled to advertise that. The more features I can advertise not having — the better.
If I am writing an application:
I may need streaming, concurrency, error handling, an effect system… Some of these are represented by many nearly indistinguishable choices. I would like to have a starter pack that makes the safest and the most approachable choice for me.
riois a kind of prelude that makes steps in this direction, choosing the effect system of
ReaderT IOfor you, among other things.
I would like to advertise the absence of unsafe functions.
For a bad example,
vectoris not something I would like to use since it makes no effort to provide a total interface. Or, for that matter,
For a good example,
protoludeexports only a single unsafe function
panicthat emits a warning upon being compiled — this means that a combination of
-Wall -Werroris a guarantee that only safe primitives are used.
This gets us to a category common to everyone: obsolete things that should go away.
base has too many of them.
- Why do we have
base, when there is
- Why do we have lazy IO in
base, when it is known to be problematic and there are many good alternatives, such as the conceptually simple
- Why do we have ports of C libraries in
base, such as
getOpt, when we have libraries that do the same in a type safe way?
- Why do we have unsafe functions like
basewhen pattern matching is the «killer feature» of Haskell?
The list goes on.
There should be a process for throwing obsolete things away, lest we drown. There is no hiding behind «blessed» alternative preludes from this. All of us need a
base that we can be proud of, that shows the best of Haskell.