RE: Haskell 98 Report
| Sorry to get this comment in so late, but it is a small | change. In the List module, the type signature for deleteBy | is not as general as it could be, given the definition. It | could be generalized to the following (no change to the definition): | | deleteBy :: (a -> b -> Bool) -> a -> [b] -> [b] | | I've found it usefully used at this more general type. Indeed, and deleteFirstsBy :: (a -> b -> Bool) -> [b] -> [a] -> [b] I can't see any reason not to do this. Furthermore, the Report omits to export deleteFirstsBy, though GHC and Hugs both remember to do so. Simon
On Wed, May 30, 2001 at 09:46:53AM -0700, Simon Peyton-Jones wrote:
| Sorry to get this comment in so late, but it is a small | change. In the List module, the type signature for deleteBy | is not as general as it could be, given the definition. It | could be generalized to the following (no change to the definition): | | deleteBy :: (a -> b -> Bool) -> a -> [b] -> [b] | | I've found it usefully used at this more general type.
Indeed, and
deleteFirstsBy :: (a -> b -> Bool) -> [b] -> [a] -> [b]
and intersectBy :: (a -> b -> Bool) -> [a] -> [b] -> [a]
| It could be generalized to the following (no change to the definition): | | deleteBy :: (a -> b -> Bool) -> a -> [b] -> [b]
Indeed, and
deleteFirstsBy :: (a -> b -> Bool) -> [b] -> [a] -> [b]
and intersectBy :: (a -> b -> Bool) -> [a] -> [b] -> [a]
Although curiously, its dual 'unionBy' cannot also take the more general type unionBy :: (a -> b -> Bool) -> [a] -> [b] -> [a] at least, not with its current specification in terms of 'nubBy'. Regards, Malcolm
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 Wan http://pantheon.yale.edu/~zw23/ ____ # Yale University, Dept of Computer Science /\___\ # P.O.Box 208285, New Haven, CT 06520-8285 ||___|
Zhanyong Wan writes: : | 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 deleteBy'' f = filter (not . f) Malcolm Wallace writes: : | > intersectBy :: (a -> b -> Bool) -> [a] -> [b] -> [a] | | Although curiously, its dual 'unionBy' cannot also take the more | general type | | unionBy :: (a -> b -> Bool) -> [a] -> [b] -> [a] | | at least, not with its current specification in terms of 'nubBy'. That suggests a reason to leave the type of intersectBy alone - the generalisation would arbitrarily favour the first list's type over the second list's type. To me, the word "intersect" implies symmetry. - Tom
Tom Pledger wrote:
Zhanyong Wan writes: : | 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
deleteBy'' f = filter (not . f)
No. deleteBy' f only deletes the *first* element that satisfies the predicate f, while filter (not . f) deletes *all* such elements. -- Zhanyong
Zhanyong Wan writes: | Tom Pledger wrote: : | > deleteBy'' f = filter (not . f) | | No. deleteBy' f only deletes the *first* element that satisfies the | predicate f, while filter (not . f) deletes *all* such elements. Oops. Sorry. I ought to become less SQL-oriented...
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
participants (6)
-
Malcolm Wallace -
Mark Tullsen -
Ross Paterson -
Simon Peyton-Jones -
Tom Pledger -
Zhanyong Wan