
I was recently surprised to discover that the maximum and maximumBy functions always return the *last* maximum, while minimum and minimumBy return the *first* minimum in the list. The following GHCi session demonstrates this: $ ghci GHCi, version 7.2.1: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer-gmp ... linking ... done. Loading package base ... linking ... done. Loading package ffi-1.0 ... linking ... done. Prelude> :module +Data.List Data.Ord Prelude Data.List Data.Ord> let list = [(1, 'B'), (1, 'A')] Prelude Data.List Data.Ord> maximumBy (comparing fst) list (1,'A') Prelude Data.List Data.Ord> minimumBy (comparing fst) list (1,'B') I would normally consider this kind of gratuitous asymmetry a bug, but seeing that these functions' implementations have been specified in the Haskell 98 Library Report, I guess they are now a permanent feature of the language. Can anybody explain the reason for this behaviour?

On 4 September 2011 21:44, Mario Blažević
I was recently surprised to discover that the maximum and maximumBy functions always return the *last* maximum, while minimum and minimumBy return the *first* minimum in the list. The following GHCi session demonstrates this:
$ ghci GHCi, version 7.2.1: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer-gmp ... linking ... done. Loading package base ... linking ... done. Loading package ffi-1.0 ... linking ... done. Prelude> :module +Data.List Data.Ord Prelude Data.List Data.Ord> let list = [(1, 'B'), (1, 'A')] Prelude Data.List Data.Ord> maximumBy (comparing fst) list (1,'A') Prelude Data.List Data.Ord> minimumBy (comparing fst) list (1,'B')
I would normally consider this kind of gratuitous asymmetry a bug, but seeing that these functions' implementations have been specified in the Haskell 98 Library Report, I guess they are now a permanent feature of the language. Can anybody explain the reason for this behaviour?
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
The asymmetry is a result of EQ and LT being treated as equivalent in both the minBy and maxBy helper functions in the report's definition of the two functions, which has opposite effects for minimumBy and maximumBy. Since the documentation doesn't specify a behavior for equal values, I could guess that it was just an oversight or that it was considered unimportant. But maybe someone more knowledgeable will correct me. Alexander Dunlap

On Monday 05 September 2011, 08:35:30, Alexander Dunlap wrote:
On 4 September 2011 21:44, Mario Blažević
wrote: I was recently surprised to discover that the maximum and maximumBy functions always return the *last* maximum, while minimum and minimumBy return the *first* minimum in the list. The following GHCi session demonstrates this:
$ ghci GHCi, version 7.2.1: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer-gmp ... linking ... done. Loading package base ... linking ... done. Loading package ffi-1.0 ... linking ... done. Prelude> :module +Data.List Data.Ord Prelude Data.List Data.Ord> let list = [(1, 'B'), (1, 'A')] Prelude Data.List Data.Ord> maximumBy (comparing fst) list (1,'A') Prelude Data.List Data.Ord> minimumBy (comparing fst) list (1,'B')
I would normally consider this kind of gratuitous asymmetry a bug, but seeing that these functions' implementations have been specified in the Haskell 98 Library Report, I guess they are now a permanent feature of the language. Can anybody explain the reason for this behaviour?
The asymmetry is a result of EQ and LT being treated as equivalent in both the minBy and maxBy helper functions in the report's definition of the two functions, which has opposite effects for minimumBy and maximumBy. Since the documentation doesn't specify a behavior for equal values, I could guess that it was just an oversight or that it was considered unimportant. But maybe someone more knowledgeable will correct me.
Alexander Dunlap
The default methods for min and max already have this: max x y = if x <= y then y else x min x y = if x <= y then x else y I think the reason for this is that if you have (a, b) = (min x y, max x y), you'll get both values even if they compare equal (and not everybody thinks that if two values compare equal, they shouldn't be distinguishable by any other means, so it might matter). Probably, the behaviour of minimum[By] and maximum[By] is intentional as an extension of this.

On 11-09-05 12:44 AM, Mario Blažević wrote:
I was recently surprised to discover that the maximum and maximumBy functions always return the *last* maximum, while minimum and minimumBy return the *first* minimum in the list.
Though not beautifully symmetric, it's beautifully dual!

This way these laws hold for non-empty lists: maximumBy f xs = last (sortBy f xs) minimumBy f xs = head (sortBy f xs) Sjoerd Visscher On Sep 5, 2011, at 6:44 AM, Mario Blažević wrote:
I was recently surprised to discover that the maximum and maximumBy functions always return the *last* maximum, while minimum and minimumBy return the *first* minimum in the list. The following GHCi session demonstrates this:
$ ghci GHCi, version 7.2.1: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer-gmp ... linking ... done. Loading package base ... linking ... done. Loading package ffi-1.0 ... linking ... done. Prelude> :module +Data.List Data.Ord Prelude Data.List Data.Ord> let list = [(1, 'B'), (1, 'A')] Prelude Data.List Data.Ord> maximumBy (comparing fst) list (1,'A') Prelude Data.List Data.Ord> minimumBy (comparing fst) list (1,'B')
I would normally consider this kind of gratuitous asymmetry a bug, but seeing that these functions' implementations have been specified in the Haskell 98 Library Report, I guess they are now a permanent feature of the language. Can anybody explain the reason for this behaviour?
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

On 11-09-05 10:42 AM, Sjoerd Visscher wrote:
This way these laws hold for non-empty lists:
maximumBy f xs = last (sortBy f xs) minimumBy f xs = head (sortBy f xs)
That's not a bad justification for the way implementation works, even if it's not the original reason behind it. I think these laws should be added to the Haddock documentation.
participants (5)
-
Albert Y. C. Lai
-
Alexander Dunlap
-
Daniel Fischer
-
Mario Blažević
-
Sjoerd Visscher