Home > Back-end >  Return the element of a list at which the function's return value is the highest
Return the element of a list at which the function's return value is the highest

Time:12-07

I have to write an Ord c => (a -> b) -> [a] -> a function that returns the value at which the first function parameter returns the highest value.

For example:

ownMax (\x -> x `mod` 5) [7,8,9] == 9

ownMax length ["words", "are", "hard"] == "words"

So far, I have the following code where I tried to use the maximumBy function as it can be used to get similar results as to what I want to achieve.

ownMax :: Ord c => (a -> b) -> [a] -> a
ownMax f (x:xs) = maximumBy((\a b -> compare (f a) (f b)) (x:xs))

Right now, it can't be loaded because of a Couldn't match type ‘Ordering’ with ‘a -> Ordering’ error.

CodePudding user response:

There is a problem with the parenthesis. You open two parenthesis for the maximumBy and this means you apply (x:xs) as parameter for the lambda expression you defined. You can define the lambda expression as first parameter and the list xs as second with:

ownMax :: Ord b => (a -> b) -> [a] -> a
ownMax f xs = maximumBy (\a b -> compare (f a) (f b)) xs

You can also work with on :: (b -> b -> c) -> (a -> b) -> a -> a -> c to apply a function on both parameters, so:

import Data.Function(on)

ownMax :: (Foldable t, Ord b) => (a -> b) -> t a -> a
ownMax f = maximumBy (compare `on` f)

or even shorter:

import Data.Function(on)

ownMax :: (Foldable t, Ord b) => (a -> b) -> t a -> a
ownMax = maximumBy . on compare
  • Related