I’m doing problem 20 on Project Euler – finding the sum of the digits of 100! (factorial, not enthusiasm).
Here is the program I wrote:
import Data.Char
main = print $ sumOfDigits (product [1..100])
sumOfDigits :: Int -> Int
sumOfDigits n = sum $ map digitToInt (show n)
I compiled it with ghc -o p20 p20.hs and executed it, getting only 0 on my command line.
Puzzled, I invoked ghci and ran the following line:
sum $ map Data.Char.digitToInt (show (product [1..100]))
This returned the correct answer. Why didn’t the compiled version work?
The reason is the type signature
use
and you will get the same thing as in GHCi (what you want).
Intis the type for machine word sized “ints” while,Integeris the type for mathematically correct, arbitrary precisionIntegers.if you type
into GHCi you will get something like
that is, for ANY type that has instances of the Enum and Num type classes,
product [1..100]could be a value of that typeshould return 93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000 which is far bigger than your machine is likely to be able to represent as a word on your machine. Probably, because of roll over
will return 0
given this, you might think
would not type check, because it has multiple possible incompatible interpretations. But, in order to be usable as a calculator, Haskell defaults to using
Integerin situations like this, thus explaining your behavior.For the same reason, if you had NOT given
sumOfDigitsan explicit type signature it would have done what you want, since the most general type is