2014-02-08 28 views
2

請幫助我理解這一點:這是一個Ghc(i)Bug?!,19 - 1不等於18嗎?

我要生成所有質爲根的「商團」(我希望這是「黃金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 

,並使用相同的參數運行

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

爲什麼改變18(rclass - 1)時,我得到不同的結果時,我把它稱爲是這樣,那rclass將於19日(當時應該(rclass -1)18 ?!

在此先感謝

+0

謝謝,我更新了 – Dender

+0

在第一種情況下,類型是'Integral t => t - > [(t,Int)]',第二種類型是'Int - > [(Int,Int)]] '。我不確定你的函數在做什麼,但是你的某個地方是否有一些整數溢出? –

+0

如果你用'fromIntegral(rclass - 1)== y'替換'(rclass - 1)== y',它會做你期望的。 –

回答

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