这是我计算斐波纳契数的代码:
f' :: (Int -> Int) -> Int -> Int
f' mf 0 = 0
f' mf 1 = 1
f' mf n = mf(n - 2) + mf(n - 1)
f'_list :: [Int]
f'_list = map (f' faster_f') [0..]
faster_f' :: Int -> Int
faster_f' n = f'_list !! n
它很好,而'n'很小。要解决大数字的问题,我想将Int-type转换为Integer:
f' :: (Integer -> Integer) -> Integer -> Integer
f' mf 0 = 0
f' mf 1 = 1
f' mf n = mf(n - 2) + mf(n - 1)
f'_list :: [Integer]
f'_list = map (f' faster_f') [0..]
faster_f' :: Integer -> Integer
faster_f' n = f'_list !! n
使用此代码我收到错误:
Couldn't match expected type `Int' with actual type `Integer'
In the second argument of `(!!)', namely `n'
In the expression: f'_list !! n
In an equation for `faster_f'': faster_f' n = f'_list !! n
好吧,我已经正确理解了列表中元素的索引不能是Integer-type。 OK:
f' :: (Integer -> Integer) -> Integer -> Integer
f' mf 0 = 0
f' mf 1 = 1
f' mf n = mf(n - 2) + mf(n - 1)
f'_list :: [Integer]
f'_list = map (f' faster_f') [0..]
faster_f' :: **Int** -> Integer
faster_f' n = f'_list !! n
但现在我收到了错误:
无法匹配预期类型
Integer' with actual type
Int' 预期类型:整数 - >整数Actual type: Int -> Integer In the first argument of `f'', namely `faster_f'' In the first argument of `map', namely `(f' faster_f')'
为什么呢?我该如何解决?
答案 0 :(得分:8)
最简单的方法是创建参数Int
(因为它们是Fibonacci数的索引,而不是数字的索引),并仅使用Integer
作为输出:
f' :: (Int -> Integer) -> Int -> Integer
f' mf 0 = 0
f' mf 1 = 1
f' mf n = mf(n - 2) + mf(n - 1)
f'_list :: [Integer]
f'_list = map (f' faster_f') [0..]
faster_f' :: Int -> Integer
faster_f' n = f'_list !! n
当然,现在你无法解决索引超出Int
范围的斐波那契数字,但实际上你的空间和时间都会用尽,更多,更快。
顺便说一下,如果你需要一个fib列表,那么“通常”的实现就是
fibs :: [Integer]
fibs = 0 : scanl (+) 1 fibs
如果您只需要某些值,则使用这些公式有一种类似于快速求幂的快速计算方法:
f(2n) = (2*f(n-1) + f(n)) * f(n)
f(2n-1) = f(n)² + f(n-1)²
答案 1 :(得分:7)
为什么?
由于f'
需要Integer -> Integer
功能,但您发送的是faster_f'
,这是Int -> Integer
功能。
我该如何解决?
最简单的方法可能是使用genericIndex
(来自Data.List
)而不是(!!)
。
答案 2 :(得分:2)
Integer是无限类型的Int,(Int仅保证覆盖从-2^29
到2^29-1
的范围,但在大多数实现中,它是完整的32或64位类型)。这就是你得到第一个错误的原因。您得到的第二个错误是因为(!!)
是一个采用列表和Int
(!!) :: [a] -> Int -> a
还有很多其他(也许更容易)的方法来计算斐波纳契数。这是一个示例,它返回指定的所有Fibonacci数列表。第一个电话是由fibCall
fib :: Integer -> Integer -> Integer -> [Integer] -> [Integer]
fib 0 _ _ l = l
fib n a b l = fib (n-1) b (a+b) (a:l)
fibCall :: Integer -> [Integer]
fibCall n = n 1 1 []
如果您只想要n th 斐波纳契数,请将[Integer]
更改为Integer
,将(a:l)
更改为a
。