Signed/unsigned integer difference between compiled and interpreted code
The following code outputs "A".
import Data.Word x :: Word x = 10 y :: Word y = 11 test = case x - y of -1 -> "A" _ -> "B" main = putStrLn $ show test
However, adding a new case that isn't matched causes the output to change:
import Data.Word x :: Word x = 10 y :: Word y = 11 test = case x - y of 5 -> "C" -1 -> "A" _ -> "B" main = putStrLn $ show test
With the extra '5 -> "C"' line in the case, the output is "B".
It gets weirder - interpreted code actually continues to match the -1 case. With the second example in a file 'T.hs', here is a GHCi session:
Prelude Main> :l *T.hs [1 of 1] Compiling Main ( T.hs, interpreted ) Ok, modules loaded: Main. *Main> main "A" *Main> :l T.hs Ok, modules loaded: Main. Prelude Main> main "B" Prelude Main>
These examples suggest to me at least 3 improvements:
- Issue a warning when a negative number is used in a case statement in unsigned context
- Interpreted code should give the same result as compiled code
- Adding a case that isn't matched shouldn't change which other patterns get matched