I've been doing project euler problems in Haskell, and often I've found the need to get the value that gives the maximum of a function.

For example,

answer = argmaximum $ map collatzLength [1..10^6]

Where collatzLength is a previously defined function.

I came up with this code, which is heavily influenced by learning Ocaml. I run a helper function that has variables that keep track of the best value index and best index so far. It works perfectly for positive lists, but it seems like there's a better way.

Is there a less clunky way to implement argmaximum?

argmaximum :: (Ord a, Num a) => [a] -> a
argmaximum lst = helper lst 0 0 0 where
  helper (x:xs) current bestVal bestIndex
    | current > bestVal = helper xs (current + 1) x current
    | otherwise = helper xs (current + 1) bestVal bestIndex
  helper null _ _ bestIndex = bestIndex
  • 3
    \$\begingroup\$ I believe you are looking for maxmimumBy (comparing collatzLength) [1..10^6] or maximumBy (compare `on` collatzLength) [1..10^6]. I’m not sure I understand how your function works, unless current > bestVal is a typo and meant to be x > bestVal. It’s late so I’m afraid I cannot review more thoroughly - I do hope at least one of my suggestions type checks. \$\endgroup\$
    – cole
    Aug 18, 2021 at 9:47

1 Answer 1


What you have implemented here is strictly speaking not argmaximum, but finding a maximum index in a list. The difference is that your argmaximum will not return the correct value for invocations that don't map from [1..?]

Instead of that, you probably wanted something that's typed as follows:

argmax :: (Ord a, Num a) => (b -> a) -> [b] -> b
argmax f (d:ds) = ...

That way you can write argmax collatzLength [500..10^6] and still get the correct answer :)

By the way: @cole suggested using maximumBy and comparing for the implementation, which I wholeheartedly agree on :)


Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.