Custom maximumBy and minimumBy in Haskell Going through the magnificent Haskell Programming from first principles, I'm currently reimplementing functions from standard libraries such as maximumBy and minimumBy.

Here are my current versions of them:

myMaximumBy :: (a -&gt; a -&gt; Ordering) -&gt; [a] -&gt; a
-- maximumBy in Data.List also throws an error on empty lists
myMaximumBy _ [] = error "empty list"
myMaximumBy f (x:xs) =
  foldr (\curMax x -&gt; if f x curMax == GT then x else curMax) x xs

myMinimumBy :: (a -&gt; a -&gt; Ordering) -&gt; [a] -&gt; a
myMinimumBy f = myMaximumBy $ flip f


I know they're not total functions, but I'll get to rewriting them with something like Maybe later on.

I'm happy for any kind of feedback on how to make the code shorter, more readable, or more idiomatic.
Since maximumBy folds a list of elements into a single element, it seems like a perfect candidate to use foldr or foldr1. However, we would need a -&gt; a -&gt; a instead of a -&gt; a -&gt; Ordering.

Let's have a look at maximum first, which can be defined via max :: Ord a =&gt; a -&gt; a -&gt; a:

maximum :: (Foldable t, Ord a) =&gt; t a -&gt; a
maximum = foldr1 max


That looks simple enough to adapt to our myMaximumBy:

myMaximumBy :: (a -&gt; a -&gt; Ordering) -&gt; [a] -&gt; a
myMaximumBy f = foldr1 (maxBy f)


We now only need a maxBy that transforms an a -&gt; a -&gt; Ordering into a a -&gt; a -&gt; a:

maxBy :: (a -&gt; a -&gt; Ordering) -&gt; a -&gt; a -&gt; a
maxBy comp x y = if x `comp` y == LT then y else x


Compared to your original solution, we now


replaced explicit recursion by foldr1
introduced a helper function that can get reused


Our new version is now easier to maintain and use.