首先,我想感谢您回答我的问题。
首先,请快速查看我的代码。您不必了解代码,只需注意类型。
这会返回一个错误,
Couldn't match expected type `Int' with actual type `Integer'
Expected type: [Int]
Actual type: [Integer]
In the first argument of `myfun', namely `primes'
In the expression: myfun primes
失败,模块加载:无。
如果我将类型更改为Int而不是Integer,我可以成功运行,没有错误,例如,“primes :: [Int]”
但是,我需要保持整数,以便程序能够获取大数字。
非常感谢您的帮助。
答案 0 :(得分:2)
错误来自(!!)
中的myfun
:
myfun (a:ab) = fibs !! (a-1) : myfun(ab)
一个较新的GHC可能会告诉你(我认为)。试试这个:
myfun (a:ab) = fibs !! ((fromInteger a)-1) : myfun(ab)
fromInteger
在结果类型中是多态的,因此类型系统推断您需要Int
。 hoogle对这类问题了解很多。
答案 1 :(得分:0)
myfun
的类型源自!!
的类型,即[a] -> Int -> a
。如果您使用数字作为列表索引,则必须将其设为Int
,无论如何,您的数字受列表容量的限制。
答案 2 :(得分:0)
您输入错误的原因是(!!)
的类型为[a] -> Int -> a
,因此,myfun
的类型推断为[Int] -> [Integer]
。
如果您确实需要Integer
s,fromIntegral
将无法帮助您;一旦素数超过maxBound
,它只会导致您的应用程序崩溃并带有负索引。
但是,(!!)
的渐近复杂度较差,因此最佳解决方案是重新编写算法,以免需要二次运行时行为。
例如,您可以改为将素数表示为要删除的索引间隔列表,而不是遍历每个传递的整个fib列表:
> import Data.List
> intervals :: [Integer]
> intervals = zipWith (-) (tail primes) primes
并收集从fibs中删除素数区间的结果:
> partC :: [Integer]
> partC = map head $ scanl (flip genericDrop) (tail fibs) intervals
我在这里使用了tail fibs
因为你跳过了斐波那契序列中的第一个数字。