这是Ghc(i)Bug?!,19 - 1不等于18?

时间:2014-02-08 14:09:56

标签: haskell

请帮助我理解这一点:

我想为一个“商组”生成所有素数根(我希望这是英语中的“素数Restklassengruppe”))

import Data.List (nub)  
primeroots rclass = filter (\(x,y) -> (18) == y) produceAllCandidates where
  produceAllCandidates = map makeOneCandidate [1..rclass] where
    makeOneCandidate elem = (elem,  (length (nub (map (\x -> (mod (elem ^ x) rclass)) [0..(rclass -1)]))))

然后我在ghci中运行它并获取

> primeroots 19
> [(2,18),(3,18),(10,18),(13,18),(14,18),(15,18)]

但是如果我将第一行中的18更改为rclass - 1(它应该产生18,并且除了15之外的所有内容都会这样做):

primeroots rclass = filter (\(x,y) -> (rclass - 1) == y) produceAllCandidates where

并使用相同的Argument

运行它
> primeroots 19
> [(2,18),(3,18),(10,18),(13,18),(14,18)]

为什么在我调用它时将18更改为(rclass-1)会得到不同的结果,rclass将为19(然后应该使(rclass -1)18?!

提前致谢

1 个答案:

答案 0 :(得分:5)

这似乎是一种类型的问题;强制输出类型为Int会产生影响:

Prelude Data.List> primeroots 19
[(2,18),(3,18),(10,18),(13,18),(14,18),(15,18)]
Prelude Data.List> primeroots 19 :: [(Int, Int)]
[(2,18),(3,18),(10,18),(13,18),(14,18)]

缩小范围:

Prelude Data.List> let foo rclass elem = map (\x -> (mod (elem ^ x) rclass)) [0..(rclass -1)]
Prelude Data.List> foo (19 :: Int) 15
[1,15,16,12,9,2,11,13,5,18,4,3,7,10,17,8,6,5,9]
Prelude Data.List> foo (19 :: Integer) 15
[1,15,16,12,9,2,11,13,5,18,4,3,7,10,17,8,6,14,1]

请注意,最后两个元素是不同的。它们分别由mod (15 ^ 17) 19mod (15 ^ 18) 19组成,溢出Int类型。

要为小数字正确执行此操作,请编写某种powMod函数,或者有点浪费并强制类型为Integer