perhaps

ajb at spamcop.net ajb at spamcop.net
Mon Aug 14 01:34:15 EDT 2006


G'day all.

Quoting kahl at cas.mcmaster.ca:

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

For simple conditionals, I argue that:

    if not (isSilly thing)
    then foo
    else bar

is no better than:

    case silliness thing of
        Sensible -> foo
        Silly    -> bar

I agree with you in part about complex conditions, however.  Complex
conditionals are inherently tricky things.  One argument I gave for
avoiding Bool is one of robustness.  Complex conditionals are often
inherently non-robust.

Suppose, for example, you write a windowing system where every window
is either Normal or Minimised.  You might have your code littered with:

    doSomething
       | isWindowNormal win && isOnScreen (windowRect win)
           = foo
       | otherwise
           = bar

Does the first part of this test mean Normal or not Minimised?  When
you allow windows that are Maximised or Shaded, the logic may be wrong.

In this case, the most robust solution might actually be to introduce
a temporary Bool view:

    isWindowVisible :: Window -> Bool
    isWindowVisible win
        = case windowState win of
            Normal    -> isOnScreen (windowRect win)
            Minimised -> False

When more window states are added, at the very least you get a
compiler warning.

>  > Oh, and one more thing: Everything I've said about Bool goes triply for
>  > Either.
>
> And for (,), of course.  ;-)

I wouldn't say "triply" in the case of (,).  The argument about
using built-in functions is much weaker for Either than for (,)
because far fewer built-in functions work with Either than with (,).

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

No, it's readability, writability and robustness vs re-use of existing
functions.  And it doesn't preclude you from re-using existing functions
if you want to:

    all isSilly things

vs:

    all (==Silly) (map silliness things)

> With respect to the name ``Silliness'', ``Silly'' intuitively corresponds
> to ``True'', but comes first, unlike ``True'' in
>
> data Bool = False | True

This is because of instance Ord.  Semantically, False < True makes
some kind of sense.  Neither Silly < Sensible nor Sensible < Silly
make the same kind of sense.

This is not to say, of course, that imposing _some_ ordering might
make pragmatic sense, say, so you could use them as Data.Map keys.

Cheers,
Andrew Bromage


More information about the Libraries mailing list