Haskell Function to get minimum of a list depending on a given function

I have to write a function like this minByFunction (\x -> -x) [1,2,3,4,5] that gives me as an answer 5. Another example would be minBy length ["a", "abcd", "xx"] gives me "a".
I though I can solve this with something like this:

minBy :: (a -> Bool) -> [a] -> Int
minBy measure list =
  case list of
    [] -> 0
    (x:xs:rest) -> if measure x > measure xs then minBy measure x:rest else minBy measure xs:rest

>Solution :

You need to use parenthesis for (x:rest), otherwise it is interpreted as (minBy measure x) : rest. Since the two recursive calls have minBy measure in common, we can however make a if … then … else … clause for the list with which we make a recursive call.

Furthermore the measure should not per se return a Bool, you want to map it on any type b that is a member of the Ord typeclass.

You also swapped the recursive calls: in case measure x < measure xs, then you should recurse with x:rest and vice versa.

Finally the function should return an a object, so the base case is a singleton list, not an empty list: for an empty list there is no minimum:

minBy :: Ord b => (a -> b) -> [a] -> a
minBy measure list =
  case list of
    [x] -> x
    (x:x2:xs) -> minBy measure (if measure x > measure x2 then x2:xs else x:xs)

Leave a Reply