Haskell:非常大的数字的最后一位

Haskell:非常大的数字的最后一位,haskell,Haskell,我想算出一个很大数字的最后一位数字。挑战在于我得到了错误 *** Exception: Prelude.!!: negative index 我认为这是不可能的。当我尝试时会发生这种情况: lastDigit [27,15,14] 这是我的代码,它基于: 在这种情况下,n变为7,modList 7给出循环序列[1,7,9,3,1,7,9,3…],这是相关保护中(!!)的第一个参数。(!!)的第二个参数给出1,因为(y:ys)是(15,14),rem(幂(15^14))4是1。请帮忙 last

我想算出一个很大数字的最后一位数字。挑战在于我得到了错误

*** Exception: Prelude.!!: negative index
我认为这是不可能的。当我尝试时会发生这种情况:

lastDigit [27,15,14]
这是我的代码,它基于:

在这种情况下,n变为7,modList 7给出循环序列[1,7,9,3,1,7,9,3…],这是相关保护中(!!)的第一个参数。(!!)的第二个参数给出1,因为(y:ys)是(15,14),rem(幂(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..]]
lastDigit::[Integer]->Integer
最后一位数字[]=1
最后一位数字[x]=x`mod`10
最后一位数字[x,y]=x^y`mod`10
最后一位数字(x:y:ys)
|y==0&&y头y/=0=1
|n==0=0
|n==9 | | n==4=(!!)(modList n)(rem(来自整数$powers(y:ys))2)
|n==2 | | n==3 | | n==7 | | n==8=(!!)(modList n)(rem(来自整数$powers(y:ys))4)
|否则=n
式中,n=mod x 10
powers xs=foldr1(^)xs

modList n=drop 3。以30$cycle[mod x 10 | x为例,您应该非常具体地说明类型,否则它们可能会在计算过程中被隐式转换。如果您将Int type添加到算法中,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转换。尝试将函数拆分为较小的函数并提供类型签名,然后您应该能够成功地将类型对齐并使用整数而不是Int进行计算。

lastDigit[27,15,14]
给了我
7
。谢谢夏。这应该是答案。可能是我的设置有问题吗?我正在运行一台64位机器,或者可能有我忽略的Int溢出问题吗?@业余爱好者:你可能忘了重新加载文件了吗?@Willem:我重新加载了。这不是问题。试试:lastDigit[2,11,32]还有,让我知道它是否有效。获取“负索引”“隐式
Int
conversion”并不完全是怎么回事——Haskell没有隐式转换。只是
(!!)
特别将
Int
作为索引,因此它强制其他类型变量为
Int
,否则它们将不受约束
Num
s,因此默认为
Integer
。这肯定会令人困惑。