7

我在 Project Euler 上做问题 20 - 找到 100 的数字之和!(因素,而不是热情)。

这是我写的程序:

import Data.Char

main = print $ sumOfDigits (product [1..100])

sumOfDigits :: Int -> Int
sumOfDigits n = sum $ map digitToInt (show n)

我用它编译ghc -o p20 p20.hs并执行它,只0在我的命令行上。

困惑的是,我调用ghci并运行了以下行:

sum $ map Data.Char.digitToInt (show (product [1..100]))

这返回了正确的答案。为什么编译的版本不起作用?

4

1 回答 1

15

原因是类型签名

sumOfDigits :: Int -> Int
sumOfDigits n = sum $ map digitToInt (show n)

采用

sumOfDigits :: Integer -> Int

你会得到和 GHCi 一样的东西(你想要的)。

Int是机器字大小“整数”Integer的类型,而 是数学上正确、任意精度的类型Integers

如果你输入

:t product [1..100]

进入 GHCi 你会得到类似的东西

product [1..100] :: (Enum a, Num a) => a

也就是说,对于具有 Enum 和 Num 类型类实例的任何类型,product [1..100]都可以是该类型的值

product [1..100] :: Integer

这应该返回,远大于您的机器可能能够在您的机器上表示单词。可能是因为翻车

product [1..100] :: Int

将返回 0

鉴于此,您可能会认为

sum $ map Data.Char.digitToInt (show (product [1..100]))

不会进行类型检查,因为它有多种可能的不兼容解释。但是,为了可以用作计算器,Haskell 默认Integer在这种情况下使用,从而解释你的行为。

出于同样的原因,如果你没有给出sumOfDigits明确的类型签名,它会做你想做的,因为最通用的类​​型是

sumOfDigits :: Show a => a -> Int
于 2012-06-24T00:52:47.740 回答