| > | 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] Indeed. We should either generalise all three deleteBy deleteFirstsBy intersectBy or none. In favour: the more general types are occasionally useful no programs stop working Against it's an unforced change perhaps some error message may get more obscure Tom wrote | 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. The point is that you can always use it at the symmetrical type too. This isn't a big issue, or I would not be considering it at this point. So I solicit feedback, and will then just decide something. Simon
On 31-May-2001, Simon Peyton-Jones <simonpj@microsoft.com> wrote:
We should either generalise all three deleteBy deleteFirstsBy intersectBy or none.
In favour: the more general types are occasionally useful no programs stop working
Actually some programs will stop working, because the types will be underconstrained, so the compiler won't know how to satisfy some type class constraint. For example: import List main = print (deleteBy (\x _y -> x > 0) 1 []) With the generalized type, you'd get an unresolved `Show' constraint. The number of real programs for which this is a problem is most likely very small, and the work-around (typically just adding an explicit type qualification) is not hard once you understand what the problem is, but figuring out what the problem is could take some time. Since it does break some obscure programs, and since it's easy enough for programmers who want a generalized version to just cut and paste the code from the Haskell report and give it a more general type signature, my preference would be to leave this out of Haskell 98, but include it in the next version of Haskell. (It would be good for someone, perhaps Simon P-J., to keep a list of issues like this which have been left out of Haskell 98 due to backwards compatibility concerns, so that they don't get forgotten about when it comes to time for the next version.) -- Fergus Henderson <fjh@cs.mu.oz.au> | "I have always known that the pursuit | of excellence is a lethal habit" WWW: <http://www.cs.mu.oz.au/~fjh> | -- the last words of T. S. Garp.
So much for my small, innocuous, non controversial suggestion :-). Fergus Henderson wrote:
On 31-May-2001, Simon Peyton-Jones <simonpj@microsoft.com> wrote:
We should either generalise all three deleteBy deleteFirstsBy intersectBy or none.
In favour: the more general types are occasionally useful no programs stop working
Actually some programs will stop working, because the types will be underconstrained, so the compiler won't know how to satisfy some type class constraint.
For example:
import List main = print (deleteBy (\x _y -> x > 0) 1 [])
With the generalized type, you'd get an unresolved `Show' constraint.
That's a good point Fergus, I hadn't noticed the potential problem here.
The number of real programs for which this is a problem is most likely very small, and the work-around (typically just adding an explicit type qualification) is not hard once you understand what the problem is, but figuring out what the problem is could take some time.
My intuition (whatever it's worth) tells me that the real programs that would be affected are close to nil. Would you agree?
Since it does break some obscure programs, and since it's easy enough for programmers who want a generalized version to just cut and paste the code from the Haskell report and give it a more general type signature,
Sure, it's easy enough, but one of the reasons I like Haskell so much over languages like C is that I almost never have to resort to programming by "cut and paste". I generally prefer to give the most general type signature for each definition. It makes programs more robust. It gives a stronger "free theorem"; in other words, I can tell more about the function by just looking at the type. For instance ... Tom Pledger wrote:
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.
But to me it seems a good reason to change the type of intersectBy: the definition isn't really symmetric, so why should the type signature be symmetric? - Mark
Fergus Henderson <fjh@cs.mu.oz.au> writes:
(It would be good for someone, perhaps Simon P-J., to keep a list of issues like this which have been left out of Haskell 98 due to backwards compatibility concerns, so that they don't get forgotten about when it comes to time for the next version.)
Such a list would indeed be useful but I think it's important that the list should record that there are reasons besides backwards compatability for leaving things as they are. IIRC, at the time that the functions were added to List, someone proposed generalisations like those currently on the table but they were rejected because they made it harder to state the relationship between the By functions and their overloaded brethren. With things as they are now, the relationship between the By functions and their overloaded variants is very, very simple to state: if foo has type foo :: (Eq a) => ty then fooBy has type fooBy :: (a -> a -> Bool) -> ty (where the additional argument is expected to be an equivalence relation) and foo = fooBy (==) and if foo has type foo :: (Ord a) => ty then fooBy has type fooBy :: (a -> a -> Bool) -> ty (where the additional argument is expected to be an reflexive, transitive relation) and foo = fooBy (<=) Making the types of the By functions as general as possible would break the consistency of this story. -- Alastair Reid reid@cs.utah.edu http://www.cs.utah.edu/~reid/
participants (4)
-
Alastair David Reid -
Fergus Henderson -
Mark Tullsen -
Simon Peyton-Jones