[Haskell-cafe] Numerics and Warnings

Barak A. Pearlmutter barak at cs.nuim.ie
Wed Apr 10 16:38:35 CEST 2013


In fiddling around with some numeric code in Haskell, I noticed some
issues.  Basically, you get warnings if you write

  energy mass = mass * c^2

but not if you write

  energy mass = mass * c * c

which seems a bit perverse.
Some more examples are below.

I understand the inference issues that cause this, but common innocuous
cases could---and I would argue, should---be addressed in ad-hoc ways.
--
Barak A. Pearlmutter
 Hamilton Institute & Dept Comp Sci, NUI Maynooth, Co. Kildare, Ireland
 http://www.bcl.hamilton.ie/~barak/

---------------- transcript ----------------

$ cat two.hs

main :: IO ()
main = do
  print 1
  print ((2::Float)^3)
  print  44444444444444444444444444444444
  print (555555555555555555555555::Int)

-- Each of the four numeric expressions printed above gives a
-- compile-time warning.  Except the last, which is the only one that is
-- actually incorrect.  Maybe ghc could eliminate some of these warnings
-- by adding extra reasonableness guards.  E.g., if the 2nd argument of
-- (^) is a constant that fits in an Int, just do that.  Basically, if
-- used as an argument to a function which has no danger of overflow,
-- default to Int without warning.  And if a constant doesn't fit in an
-- Int, jamming it into one is an error.  Or at least a warning!

$ ghc --version
The Glorious Glasgow Haskell Compilation System, version 7.6.2

$ ghc -Wall two.hs
[1 of 1] Compiling Main             ( two.hs, two.o )

two.hs:3:9: Warning:
    Defaulting the following constraint(s) to type `Integer'
      (Num a0) arising from the literal `1' at two.hs:3:9
      (Show a0) arising from a use of `print' at two.hs:3:3-7
    In the first argument of `print', namely `1'
    In a stmt of a 'do' block: print 1
    In the expression:
      do { print 1;
           print ((2 :: Float) ^ 3);
           print 44444444444444444444444444444444;
           print (555555555555555555555555 :: Int) }

two.hs:4:20: Warning:
    Defaulting the following constraint(s) to type `Integer'
      (Integral b0) arising from a use of `^' at two.hs:4:20
      (Num b0) arising from the literal `3' at two.hs:4:21
    In the first argument of `print', namely `((2 :: Float) ^ 3)'
    In a stmt of a 'do' block: print ((2 :: Float) ^ 3)
    In the expression:
      do { print 1;
           print ((2 :: Float) ^ 3);
           print 44444444444444444444444444444444;
           print (555555555555555555555555 :: Int) }

two.hs:5:10: Warning:
    Defaulting the following constraint(s) to type `Integer'
      (Num a0)
        arising from the literal `44444444444444444444444444444444'
        at two.hs:5:10-41
      (Show a0) arising from a use of `print' at two.hs:5:3-7
    In the first argument of `print', namely
      `44444444444444444444444444444444'
    In a stmt of a 'do' block: print 44444444444444444444444444444444
    In the expression:
      do { print 1;
           print ((2 :: Float) ^ 3);
           print 44444444444444444444444444444444;
           print (555555555555555555555555 :: Int) }
Linking two ...

$ ./two
1
8.0
44444444444444444444444444444444
-5035712355010463517



More information about the Haskell-Cafe mailing list