Search code examples
haskellmaxcomparison

Ord comparing, but returns the smallest one


I compare list's length and then size of the first element, this way:

(maximumBy (comparing length <> comparing head)) sx

This code returns longest list and if there are multiple that are same length it will return the one that has biggest first element.

Is there an easy way to modify this to return second comparison to return the one that has the smallest first element?


Solution

  • You can make use of Down which reverses the order of comparing:

    import Data.Ord(Down(Down))
    
    (maximumBy (comparing length <> comparing (Down . head))) sx

    or you can flip the two operands when you are comparing the value:

    (maximumBy (comparing length <> flip (comparing head))) sx

    That being said, you should be careful with comparing head. Empty lists have no head, so that can result in an error if you are comparing two empty lists.

    You can, like @DanielWagner says, make use of take 1. This works because lists [a] are an instance of Ord as well, given a is an instance of Ord. In that case the lists are ordered lexicographically. For lists with one or more elements, this thus means that we order by the first element:

    maximumBy (comparing length <> flip (comparing (take 1))) sx