On 17-May-2000, Keith Wansbrough <[EMAIL PROTECTED]> wrote:
> Moving this thread to the Haskell list...
> 
> Summary: the Haskell 98 Report claims
> 
> minimumBy :: (a -> a -> Ordering) -> [a] -> a
> 
> but Hugs and GHC implement
> 
> minimumBy :: (a -> a -> a) -> [a] -> a
> minimumBy = foldl1
> 
> Carl writes:
> 
> > Sigbjorn Finne <[EMAIL PROTECTED]> writes:
> > 
> > > This a doc bug on the GHC (and Haskell report) side -
> > > Hugs98's List.minimumBy type is the right one (and also
> > > the type of the *defn* in the Lib Report.)

The Haskell Library Report is clearly inconsistent here.

> > mimimumBy :: (a -> a -> Ordering) -> [a] -> a
> > 
> > seems much more useful than
> > 
> > mimimumBy = foldl1
> > maximumBy = foldl1
> > 
> > Why do you say the latter is "right"?

Hmm...
Take a look at 7.6 in the Haskell Library Report:

 |   7.6  The "By" operations
 | 
 |    By convention, overloaded functions have a non-overloaded counterpart
 |    whose name is suffixed with "By".
 ...
 |    The "By" variants are as follows: [...] maximumBy, minimumBy.

OK, based on this, all we need to do is to look up the type of
`minimum', and figure out the corresponding type for the non-overloaded
counterpart.  So, consulting the section A.1 of Haskell Report,
we find that the type of `minimum' is

 |   minimum          :: Ord a => [a] -> a

But the correct type for the non-overloaded counterpart of this
is not so clear, because `Ord' has a bunch of different methods:

 |    class  (Eq a) => Ord a  where
 |        compare              :: a -> a -> Ordering
 |        (<), (<=), (>=), (>) :: a -> a -> Bool
 |        max, min             :: a -> a -> a
 |            -- Minimal complete definition:
 |            --      (<=) or compare

It is not clear which of these should be used as the parameter for
"By" variant.  I see three alternatives:

(1)
Section 7.6 does gives us a hint:

 |    ... when the "By" function replaces
 |    an Ord context by a binary predicate, the predicate is assumed to
 |    define a total ordering.

Here the phrase "binary predicate" suggests we should use something of
type `a -> a -> Bool'.  So perhaps we should use `<='.

(2)
On the other hand, the other "By" variants of functions that take
something constrained by `Ord', i.e. `insertBy' and `sortBy', use an
argument of type `a -> a -> Ordering'.  So for consistency `minimumBy'
should do the same.  This is probably a more compelling argument.

(3)
The Haskell Libary Report's _definition_ of those functions
gives us yet another alternative, using a parameter of type `a -> a -> a',
i.e. `min' for `minimumBy' and `max' for `maximumBy'.
This interpretation is apparently supported by the status quo
amongst implementations (at least Hugs and ghc).
But it is somewhat inconsistent with the choice made for `insertBy'
and `sortBy', and as Carl Whitty argued, it is not very useful,
since in that case `minimumBy' and `maximumBy' become just alternative
names for `foldl1'.

Of these three solutions, I personally favour (2), unless there a
significant amount of code for the existing implementations would be
broken if they changed, which I suspect is unlikely.

If solution (3) is adopted, the above-quoted phrase "binary
predicate" from 7.6 should be replaced by "comparison function":

        ... when the "By" function replaces an Ord context by a
        comparison function, the comparison function is assumed to
        define a total ordering.

Likewise that paragraph should be reworded if solution (2) is adopted.

-- 
Fergus Henderson <[EMAIL PROTECTED]>  |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>  |  of excellence is a lethal habit"
PGP: finger [EMAIL PROTECTED]        |     -- the last words of T. S. Garp.

Reply via email to