5

Say one wants to calculate the function:

f (x,y) = ((x `mod` 3)+(y `mod` 3)) `mod` 2

Then, if one expands f (-1,0) manually, one gets:

((-1 `mod` 3)+(0 `mod` 3)) `mod` 2
1

If one however uses an inline function, the result is:

let f (x,y) = ((x `mod` 3)+(y `mod` 3)) `mod` 2 in f (-1,0)
0

What happens when storing the function that yields not the expected result?

I assume this is because f uses Integral instead of Int?

Tikhon Jelvis
  • 67,485
  • 18
  • 177
  • 214
Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555
  • BTW (and indeed closely related to the problem): you don't need all those parens; `mod` binds automatically more tightly (`infixl 7 mod` vs `infixl 6 +`). You'd be fine with ``((-1)`mod`3 + 0`mod`3) `mod` 2``. – leftaroundabout Sep 18 '14 at 00:02
  • @leftaroundabout: True, the brackets were added in order to track down the problem :(. – Willem Van Onsem Sep 18 '14 at 00:23

1 Answers1

9

Looks like it's a matter of parsing. -1 `mod` 3 gets parsed as -(1 `mod` 3) and not (-1) `mod` 3.

*Main> -(1 `mod` 3)
-1
*Main> (-1) `mod` 3
2

Honestly, the way unary - works in Haskell is a bit of a hack that I personally find confusing. If I really need a negative literal, I usually just add the extra parentheses to be sure.

Another thing to consider is that Haskell has two modulo functions, mod and rem, that treat negative numbers differently. For more details, look to these two other questions.

Community
  • 1
  • 1
Tikhon Jelvis
  • 67,485
  • 18
  • 177
  • 214