La razón es el tipo de firma
sumOfDigits :: Int -> Int
sumOfDigits n = sum $ map digitToInt (show n)
uso
sumOfDigits :: Integer -> Int
y obtendrá el mismo que en GHCi (lo que quiere).
Int
es el tipo de máquina de tamaño de palabra "ints" mientras que Integer
es el tipo matemáticamente correcto, precisión arbitraria Integers
.
si escribe
:t product [1..100]
en GHCi usted consigue algo como
product [1..100] :: (Enum a, Num a) => a
que es, para cualquier tipo que tiene instancias de las clases tipo de enumeración y Num, product [1..100]
podría ser un valor de ese tipo
product [1..100] :: Integer
deberían volver 93326215443944152681699238856266700490715 968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000 que es mucho más grande de lo que su máquina probablemente pueda representar como palabra en su máquina. Probablemente, debido a rodar sobre
product [1..100] :: Int
devolverá 0
Ante esto, se podría pensar
sum $ map Data.Char.digitToInt (show (product [1..100]))
no habría tipo de comprobación, ya que tiene múltiples interpretaciones posibles incompatibles. Pero, para ser utilizable como una calculadora, Haskell usa de manera predeterminada Integer
en situaciones como esta, explicando así su comportamiento.
Por la misma razón, si no hubiera dado sumOfDigits
un tipo de firma explícita lo habría hecho lo que quiere, ya que el tipo más general es
sumOfDigits :: Show a => a -> Int