1

I am trying to write a One line function where you enter a number and a List, and it returns the highest value.

For example:

Input: getMax 5 [1,4,7]
Output: 7

Here is my current code:

getMax :: (Ord a) => a -> [a] -> a
getMax f xs = foldr max f xs

Now I want to extend my function so that instead of a number I can enter a Lamda function to be compared.

For example:

Input: getMax (\x -> mod x 5) [1,4,7]
Output: 4

But I cannot get it to work.

I get an error message:

No instance for (Show (Integer -> Integer))

which I don't really understand.

I tried to change the type signature, but that did not help.

thanks in advance!

2
  • Your function assumes that the first argument is the "minimum" max to use, if the list is empty or has no value greater than the minimum. The function you try to pass in the second example is not such a minimum; it's something you (apparently) want to apply to each list value before computing a maximum: getMax 5 (map (\x -> mod x 5) [1,4,7]), perhaps? Commented Dec 1, 2022 at 14:08
  • I'd recommend checking out maximumBy function Commented Dec 1, 2022 at 14:41

1 Answer 1

1

Your foldr function should work with f, and pick one of the two items x₁ or x₂ based on whether f x₁ is less than or equal to f x₂, so:

getMax :: Ord b => (a -> b) -> [a] -> a
getMax f xs = foldr1 g xs
    where g x₁ x₂
            | … = …
            | otherwise = …

where I leave implementing the parts as an exercise.

Sign up to request clarification or add additional context in comments.

5 Comments

Thank you, but my goal is to implement a one line function. So I cannot use Guards
@DanielJackson3: you can use if ... then ... else ... which is equivalent to using guards.
@WillemVanOnsem You can also just write guards on one line, no? Super gross, but with as pointless a requirement as "one line function" it's as reasonable as anything.
@amalloy: yes, although it makes it a bit ugly. The one-line requirements is indeed strange, since it will discourage people from writing elegant code.
An alternative that doesn't involve guards would be to do a decorate-undecorate thing. max (f x1, x1) (f x2, x2) almost does the right thing except it also compares x1 and x2; but in Data.Semigroup there is the Arg data type, and max (Arg (f x1) x1) (Arg (f x2) x2) behaves just right.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.