user1002430
user1002430

Reputation:

Good/Correct way to write this due to Haskell operator precedence?

This code works:

40 * sum [1..10]

This code does not:

40 * sum $ map id [1..10]

I now understand it to be because this is grouped into (40 * sum) (map id [1..10]) due to operator precedence instead of what I think it should be, which is (40 *) (sum (map id [1..10])).

Is there a proper way to write this in Haskell other than using parentheses?

Upvotes: 0

Views: 79

Answers (2)

enrique
enrique

Reputation: 502

The answer which is closer to your original expression, 40 * sum $ map id [1..10], is to consider that (*) is just the name of a function, so that parenthesis are just part of the name, not grouping symbols, and rewriting your expression as:

(*) 40 . sum $ map id [1..10]

This way also avoids problems with precedence, which affects only to infix form of binary functions (operators).

Functional programming encourage the use of composition versus application, so a more "proper" way, as you are asking for, would be this slight variation:

(*) 40 . sum . map id $ [1..10]

Upvotes: 0

bheklilr
bheklilr

Reputation: 54058

I know of no way to write this expression properly without using parentheses, but I would prefer to see something more like one of the following

(40 *) $ sum $ map id [1..10]

40 * (sum $ map id [1..10])

(*) 40 $ sum $ map id [1..10]

(40 *) . sum . map id $ [1..10]

Instead of

(40 *) (sum (map id [1..10]))

You could get rid of the parens in this particular expression if you aliased (*) to a function rather than an operator:

mult :: Num a => a -> a -> a
mult = (*)

expr :: Int
expr = mult 40 $ sum $ map id [1..10]

However, I wouldn't worry too much about having some parentheses, in this case it isn't a huge deal to have them. Introducing a new name just to circumvent a small amount of normal syntax would just make your code more difficult to read and understand.

Upvotes: 5

Related Questions