交互运行我的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 = 13481503k = 11237126,m = 46340

前者返回一个完全不同的数字,当在ghci中调用相同的值,即modPow 13481503 11237126 46340

在先进的感谢

可以定义modPowInt -> Int -> Int -> Int,即,它接受和返回Int S(64位整数),因此所有的操作都模64个比特。

当您手动执行表达式时,GHCI将您的号码上传到Integer(它的大小无限制),产生正确的输出。

+0

有没有办法做同样的事情,而不改变签名?谢谢 – trunks1ace

+0

不,如果返回类型的大小有限(64位),则不能返回无限的'Integer'类型.. – randomir

看表达的类型,您使用:

> :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中,都会发生这种情况;你误诊了两次测试之间的显着差异。