I'm looking for feedback on my solution to the following prompt:
Given an array of ints, return the index such that the sum of the elements to the right of that index equals the sum of the elements to the left of that index. If there is no such index, return Nothing. If there is more than one such index, return the left-most index. Example:
peak([1,2,3,5,3,2,1]) = 3, because the sum of the elements at indexes 0,1,2 == sum of elements at indexes 4,5,6. We don't sum index 3.
- Is the solution best defined recursively? Or is there some kind of higher-order function that I could use?
- The function
peak'takes four arguments. That feels a little unwieldy. Any reasonable way to shorten that parameter list?
- Conventional programming wisdom says to avoid "magic numbers", so I introduced some bindings in the
letclause. Does that make
peakeasier to read, or does it just seem like bloat?
peak :: [Int] -> Maybe Int peak numbers = let leftSum = 0 rightSum = sum numbers startingIndex = 0 in peak' numbers leftSum rightSum startingIndex peak' :: [Int] -> Int -> Int -> Int -> Maybe Int peak'  _ _ _ = Nothing peak' (x:xs) leftSum rightSum index | leftSum + x == rightSum = Just index | otherwise = peak' xs (leftSum + x) (rightSum - x) (index + 1)