kahl at kahl at
Mon Aug 14 00:15:05 EDT 2006

Andrew Bromage <ajb at> wrote:

 > I also think that 80% of the uses of Bool are wrong.
 > Any time that you see this:
 >     doSomething :: Bool -> Stuff -> MoreStuff
 > Not only is it not obvious what Bool means, it's not obvious what
 > the sense of it should be.  In fact, almost every time I see an
 > argument in a function that I haven't used for a while, I find
 > myself reaching for the documentation, because I can never remember
 > what it means.
 > [...]
 > In Haskell, it takes one line to declare a new enumerated type with
 > just a few elements.  For very little effort, you get a huge payoff
 > in usability:
 >     data Silliness = Silly | Sensible
 >     silliness :: PossiblySillyThing -> Silliness
 >     -- Now I don't have to remember what the first argument means or
 >     -- which way around it's supposed to be.  It's obvious from the type.
 >     doSomething :: Silliness -> Stuff -> MoreStuff
 > I'm sorry to go through this in detail, but this stuff is easy to
 > forget.

Unfortunately the relevant prelude functions, like not, &&, all, ...,
are all written in a way that they don't work for Silliness.

 > Oh, and one more thing: Everything I've said about Bool goes triply for
 > Either.

And for (,), of course.  ;-)

The trade-off currently is readability versus re-use of existing functions.

A generic prelude, where ``not Silly'' is automagically ``Sensible'',
might bring some of the best of both worlds, but could also spawn
new confusion: with the definition above, we would probably get:

< forall x :: Silliness  .  Silly    && x = Silly
< forall x :: Silliness  .  Sensible || x = x

With respect to the name ``Silliness'', ``Silly'' intuitively corresponds
to ``True'', but comes first, unlike ``True'' in

data Bool = False | True

``Getting the names right'' is important, but hard.


More information about the Libraries mailing list