tl;dr: Looking for early feedback on making max
and maximumBy
left-biased; read this for more.
It is a little-known*, and possibly rarely-relevant, fact that the default implementation of max
in the Ord
class is right-biased, while the default implementation of min
is left-biased. By this, I mean that if two terms of a type compare equal (according to (==)
), applying default min
to the terms will return the first and applying default max
will return the second. (I don’t know the reason behind this choice, though the Haskell 2010 Language Report specifies it, as did Haskell 98.)
This convention—it’s only a convention, and an undocumented one at that—extends to the implementations of minimumBy
and maximumBy
(in both of the Data.Foldable
and Data.Foldable1
modules), which can’t use the min
and max
functions from the relevant Ord
instance and so need to assume their own bias direction. Consistent with default min
and max
, they are left- and right-biased, respectively.
It’s not often the case that two equal-up-to-(==)
terms will be observably different from each other, so outside of performance-related concerns this bias direction doesn’t matter much. However, one type for which (==)
-equality is intentionally not the same as observational equality is Data.Semigroup.
Arg
, which exists pretty much only for the purpose of finding a minimum or maximum over its first field and then extracting the second field, which doesn’t participate in the comparison. min
and max
for Arg
are both declared with left-biased implementations, in what I assume was an intentional choice backed by a belief that, for the use case targeted by this data type (i.e., when the difference between (==)
-equality and observational equality is relevant), a left bias is more useful than a right bias.
This state of affairs leads to minimumBy compare
being practically equivalent to minimum
, but maximumBy compare
only being equivalent to maximum
on types where the max
member of Ord
hasn’t been defined to be left-biased—not Arg
, in other words.
In light of this, and bearing in mind that most similar functions in base
are left-biased by convention, I’m putting forward a CLC proposal in its early stages to change the default implementation of max
, and the implementations of maximumBy
, to be left-biased; and to note this as the preferred bias direction in the Ord
class documentation. This would be a wide-reaching change, and while I can hope that its practical impact on existing programs would be near-zero, it’s the sort of subtle change in behavior that could easily have all sorts of unexpected consequences.
If you might know of a situation that would be sensitive to this change, please weigh in. Start reading at this comment, please.
(Enthusiastic support is also welcome. )
*: Wildly extrapolating from the fact that I didn’t know it until recently, and the reporter of this issue claims that all of their peers that they asked didn’t know it either.