当使用ghci以交互方式运行Haskell代码并将其作为模块加载时,我得到了不同的结果

时间:2017-10-10 19:28:21

标签: haskell ghc ghci exponential

从.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 = 11237126m = 46340

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

3 个答案:

答案 0 :(得分:4)

查看您使用的表达式的类型:

> :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

答案 1 :(得分:3)

您将modPow定义为Int -> Int -> Int -> Int,即它接受并返回Int s(64位整数),因此所有操作都是模64位。

当您手动执行表达式时,GHCI会将您的数字向上转换为Integer(大小不受限制),从而产生正确的输出。

答案 2 :(得分:1)

你正在筹集5,618,563的力量。这是巨大的号码。您可以用Int表示的最大数字(假设它是带符号的64位整数)是(2 ^ 63) - 1。从5,618,563开始> 63,任何提升到500万的力都不能适合Int(除非“任何东西”是1,0或-1)。所以modPow :: Int -> Int -> Int -> Int将会溢出

输入相同的操作而不类型签名将默认为IntegerInt不限于64位。因此计算不会溢出并且会给出真实的结果。无论您是在模块中还是在GHCi中进行,都会发生这种情况;你误诊了两次测试之间的显着差异。