我在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]))
这返回了正确的答案.为什么编译版本不起作用?
Phi*_* JF 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
应该返回远大于您的机器可能在您的机器上表示为单词的93326215443944152681699238856266792963895217599993816214685929638952175991832299156089414639761565182862536979208272237582511852109168640000000000000000000000000000.可能是因为翻身
product [1..100] :: Int
将返回0
考虑到这一点,你可能会想
sum $ map Data.Char.digitToInt (show (product [1..100]))
不会打字检查,因为它有多种可能不兼容的解释.但是,为了可以用作计算器,Haskell默认Integer在这种情况下使用,从而解释你的行为.
出于同样的原因,如果你没有给出sumOfDigits一个明确的类型签名,它就会做你想要的,因为最常见的类型是
sumOfDigits :: Show a => a -> Int
| 归档时间: | 
 | 
| 查看次数: | 173 次 | 
| 最近记录: |