Search code examples
haskell

Seemingly odd output for Haskell function


I have a Haskell function:

sumSquareOrSquareSum' :: (Num a, Ord a) => a -> a -> a
sumSquareOrSquareSum' x y = (\sumSquare squareSum ->
                              if sumSquare > squareSum
                              then sumSquare
                              else squareSum) (x^2 + y^2) (x+y)^2

If I run it as sumSquareOrSquareSum' 1 2 I get the answer 25 instead of the 9 I would expect.

If I make both branches return squareSum I get 9, if both return sumSquare I get 25. If I make the GT a LT I get 9, so it appears to be the first term that's evaluating weirdly, or at least in a manner that I don't understand.

I can fix the problem by putting parentheses around the (x+y)^2 term making the final line:

else squareSum) (x^2 + y^2) ((x+y)^2)

So, I know how to fix it, but I'm not at all clear as to why there is a problem in the first place. Any insight would be appreciated.


Solution

  • Function application binds more tighly than operators, so

    f x^2
    

    is evaluated as

    (f x)^2
    

    instead of the

    f (x^2)
    

    you expect. This still applies to functions with two parameters, so

    max a b^2
    

    is actually

    (max a b)^2
    

    Flip the parameters like max b^2 a and see the error message as haskell is trying to interpret that as (max b)^(2 a).