交互运行我的Haskell代码时使用ghci中我得到不同的结果,并从名为.hs文件加载它作为一个模块时
问题描述:
代码加载:进入交互交互运行我的Haskell代码时使用ghci中我得到不同的结果,并从名为.hs文件加载它作为一个模块时
modPow :: Int -> Int -> Int -> Int
modPow a k m = (a^2 `mod` m)^(k `div` 2)
代码:
(13481503^2 `mod` 46340)^(11237126 `div` 2)
即a = 13481503
,k = 11237126
,m = 46340
前者返回一个完全不同的数字,当在ghci中调用相同的值,即modPow 13481503 11237126 46340
在先进的感谢
答
可以定义modPow
如Int -> Int -> Int -> Int
,即,它接受和返回Int
S(64位整数),因此所有的操作都模64个比特。
当您手动执行表达式时,GHCI将您的号码上传到Integer
(它的大小无限制),产生正确的输出。
答
看表达的类型,您使用:
> :t (13481503^2 `mod` 46340)^(11237126 `div` 2)
(13481503^2 `mod` 46340)^(11237126 `div` 2) :: Integral a => a
ghci
默认为Integer
时用力要评估Integral a => a
类型的值(与通过交互式解释到show
隐式调用发生),而你的函数返回一个Int
。
答
你正在提高5,618,563的能力。这是一个巨大的号码。您可以用Int
(假设它是一个有符号的64位整数)表示的最大数字是(2^63) - 1
。由于5,618,563> 63,任何增加到500万的功率都不能适合Int
(除非“任何东西”是1,0或-1)。所以modPow :: Int -> Int -> Int -> Int
将溢出
进入相同的操作没有一个类型签名将默认为Integer
,这并不局限于64位的方式Int
。所以计算不会溢出,并会给出真实的结果。不管你是在一个模块还是在GHCi中,都会发生这种情况;你误诊了两次测试之间的显着差异。
有没有办法做同样的事情,而不改变签名?谢谢 – trunks1ace
不,如果返回类型的大小有限(64位),则不能返回无限的'Integer'类型.. – randomir