Haskell 98 Report
Mark Tullsen
tullsen@cs.yale.edu
Wed, 30 May 2001 19:59:44 -0400
Zhanyong Wan wrote:
>
> Hello Simon,
>
> Looking at the definition for deleteBy:
>
> deleteBy :: (x -> a -> Bool) -> x -> [a] -> [a]
> deleteBy eq x [] = []
> deleteBy eq x (y:ys) = if x `eq` y then ys else
> y : deleteBy eq x ys
>
> I can't help wondering why it isn't
>
> deleteBy' :: (a -> Bool) -> [a] -> [a]
> deleteBy' f [] = []
> deleteBy' f (y:ys) = if f y then ys else
> y : deleteBy' f ys
>
> The point is that in the definition of deleteBy, all references to eq
> and x are in the form (eq x), and hence the two parameters can be
> combined. Is there a reason that the current design was favored when
> Prelude was designed? Thanks.
>
> - Zhanyong
Zhanyong,
I didn't mean to open up a can of worms! Although, when viewed in
isolation, it would make sense to change deleteBy as you suggest;
but when we look at the conventions of the List module, I think that
it would be undesirable, even if we didn't care about breaking programs,
because it would break the "xBy" convention described below.
Originally we had this:
delete :: Eq a => a -> [a] -> [a]
deleteBy :: (a -> a -> Bool) -> a -> [a] -> [a]
And all the functions "x" with a "xBy" form have types which
are related in a particular way, for some functor f:
x :: Eq a => f a
xBy :: (a -> a -> Bool) -> f a
Now, if we generalize the type of deleteBy as I previously suggested,
we have these two types:
delete :: Eq a => a -> [a] -> [a]
deleteBy :: (a -> b -> Bool) -> a -> [b] -> [b]
And it is still the case that functions "x" and "xBy" have types
which are related as follows (generalizing the rule):
x :: Eq a => f a a
xBy :: (a -> b -> Bool) -> f a b
(Where we would instantiate 'b' to 'a' for "xBy" functions which
have a less general type.)
- Mark