
On 2008-03-13, Ketil Malde
Aaron Denney
writes: Well, the way the report specifies that max's default definition is. I'd actually favor making that not an instance function at all, and instead have max and min be external functions.
If you permit a naïve question:
Prelude> :i Ord class (Eq a) => Ord a where compare :: a -> a -> Ordering (<) :: a -> a -> Bool (>=) :: a -> a -> Bool (>) :: a -> a -> Bool (<=) :: a -> a -> Bool max :: a -> a -> a min :: a -> a -> a
..while all functions could be easily derived from 'compare'. Or from the Eq instance's (==) and (<), say.
What is the reason for this? Efficiency? (Which couldn't be handled equally well by RULES?) Otherwise, it looks like an invitation for writing inconsistent instances.
My impression (which may not be entirely accurate) is not primarily for efficiency (though that is one reason), but for ease of implementation. It may be easier in some cases to think through the various cases of compare, or to just figure out what (<=) is. Either of these is sufficient (perhaps in combination with (==) from the superclass). You can write things so that any of (<), (<=), (>), or (>=) are sufficient, but for writing the default compare, it's easiest to know ahead of time which you are basing it on, so definitions don't get circular. max and min seem to have neither justification going for them, although I suppose it's technically possible to write compare in terms of them and (==). I don't think GHC's RULES were around when Haskell 98 was being formalized, nor is it clear that one compiler's method should let other efficiency concerns go by the wayside. Of course, it would be nice to be able to write (==) in terms of compare. While doable manually there's no way to default it to that "smartly". There are similar issues with Functor and Monad. ISTR some discussion about this on the list previously. -- Aaron Denney -><-

In gmane.comp.lang.haskell.prime Aaron Denney
Prelude> :i Ord class (Eq a) => Ord a where compare :: a -> a -> Ordering (<) :: a -> a -> Bool (>=) :: a -> a -> Bool (>) :: a -> a -> Bool (<=) :: a -> a -> Bool max :: a -> a -> a min :: a -> a -> a
..while all functions could be easily derived from 'compare'. Or from the Eq instance's (==) and (<), say.
What is the reason for this? Efficiency? (Which couldn't be handled equally well by RULES?) Otherwise, it looks like an invitation for writing inconsistent instances.
My impression (which may not be entirely accurate) is not primarily for efficiency (though that is one reason), but for ease of implementation. [...] max and min seem to have neither justification going for them, although I suppose it's technically possible to write compare in terms of them and (==).
I am quite late to join this thread, but as I just read the thread about Conal's AddBounds where he had a very valid point for implementing min/max without resorting to <= or compare: min [] ys = [] min xs [] = [] min (x:xs) (y:ys) | cmp == LT = (x:xs) | cmp == GT = (y:ys) | cmp == EQ = x:min xs ys where cmp = compare x y This is a properly lazy implementation for min (the one in GHC's prelude is not), as it is able to calculate (take 5 $ min [1,2..] [1,2..]). This is not possible if min has to wait for compare or <= to compare the full lists before returning the head. Regards, Michael Karcher

On Tue, Apr 22, 2008 at 05:28:27PM +0000, Michael Karcher wrote:
I am quite late to join this thread, but as I just read the thread about Conal's AddBounds where he had a very valid point for implementing min/max without resorting to <= or compare:
min [] ys = [] min xs [] = [] min (x:xs) (y:ys) | cmp == LT = (x:xs) | cmp == GT = (y:ys) | cmp == EQ = x:min xs ys where cmp = compare x y
This is a properly lazy implementation for min (the one in GHC's prelude is not), as it is able to calculate (take 5 $ min [1,2..] [1,2..]). This is not possible if min has to wait for compare or <= to compare the full lists before returning the head.
In addition, you need special min and max functions to implement IEEE floating point properly. Of course, floating point is odd in general, but we should be correct when we can. John -- John Meacham - ⑆repetae.net⑆john⑈
participants (3)
-
Aaron Denney
-
John Meacham
-
usenet@mkarcher.dialup.fu-berlin.de