请帮助我理解这一点:
我想为一个“商组”生成所有素数根(我希望这是英语中的“素数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?!
提前致谢
答案 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) 19
和mod (15 ^ 18) 19
组成,溢出Int
类型。
要为小数字正确执行此操作,请编写某种powMod
函数,或者有点浪费并强制类型为Integer
。