我试图弄清楚一个非常大的数字的最后一个数字。我遇到的挑战是错误
*** Exception: Prelude.!!: negative index
我认为应该不可能。当我尝试时会发生这种情况:
lastDigit [27,15,14]
以下是我的代码,该代码基于https://brilliant.org/wiki/finding-the-last-digit-of-a-power/:
在这种情况下,n变为7,modList 7给出重复序列[1,7,9,3,1,7,9,3 ...],这是(!!)中的第一个参数相关警卫。 (!!)的第二个参数给出1,因为(y:ys)是(15,14)而rem(powers(15 ^ 14))4是1.请帮助。
lastDigit :: [Integer] -> Integer
lastDigit [] = 1
lastDigit [x] = x `mod` 10
lastDigit [x,y] = x ^ y `mod` 10
lastDigit (x:y:ys)
| y == 0 && head ys /= 0 = 1
| n == 0 = 0
| n == 9 || n == 4 = (!!) (modList n) (rem (fromIntegral $ powers (y:ys)) 2)
| n == 2 || n == 3 || n == 7 || n == 8 = (!!) (modList n) (rem (fromIntegral $ powers (y:ys)) 4)
| otherwise = n
where n = mod x 10
powers xs = foldr1 (^) xs
modList n = drop 3 . take 30 $ cycle [mod x 10| x <- map (n^) $ take 4 [1..]]
答案 0 :(得分:1)
您应该对类型非常具体,否则它们可能会在计算过程中被隐式转换。如果将Int类型添加到算法中,ghc将不会抱怨并遇到负索引异常
(fromIntegral $ powers (y:ys)) 2 :: Int)
但如果你提供
(fromIntegral $ powers (y:ys)) 2 :: Integer)
将导致
• Couldn't match expected type ‘Int’ with actual type ‘Integer’
• In the second argument of ‘(!!)’, namely
‘(rem (fromIntegral $ powers (y : ys)) 2 :: Integer)’
正如您所看到的,那里有一个隐式的Int转换。尝试将您的函数拆分为较小的函数并提供类型签名,然后您应该能够成功对齐类型并使用Integers而不是Int进行计算。