Powodem jest podpis typu
sumOfDigits :: Int -> Int
sumOfDigits n = sum $ map digitToInt (show n)
użycie
sumOfDigits :: Integer -> Int
a dostaniesz to samo, co w GHCi (co chcesz).
Int
to typ słowa maszynowego o rozmiarze "int", natomiast Integer
to typ matematycznie poprawnej, arbitralnej precyzji Integers
.
jeśli wpiszesz
:t product [1..100]
do GHCi dostaniesz coś
product [1..100] :: (Enum a, Num a) => a
to znaczy dla każdego typu, który ma instancje klas typu Enum i Num product [1..100]
mógłby być wartością tego typu powinien zostać zwrócony 93326215443944152681699238856266700490715. 9682643816214685929638952175999932299156089414639761565182862536979208272237582511852109168640000000000000000000000, który jest o wiele większy niż Twój komputer, prawdopodobnie będzie mógł reprezentować jako słowo na twoim komputerze. Prawdopodobnie z powodu przewrócenia
product [1..100] :: Int
powróci 0
Biorąc pod uwagę to, można by pomyśleć
sum $ map Data.Char.digitToInt (show (product [1..100]))
nie typ kontroli, ponieważ ma wiele możliwych interpretacji niezgodnych. Jednak, aby być użytecznym jako kalkulator, Haskell domyślnie używa Integer
w takich sytuacjach, wyjaśniając w ten sposób twoje zachowanie.
Z tego samego powodu, jeśli nie dał sumOfDigits
wyraźny typ podpis uczyniłby to, co chcesz, ponieważ najbardziej ogólny typ to
sumOfDigits :: Show a => a -> Int