2015-09-06 40 views
0

我在執行函數時遇到了問題,該函數使用列表解析計算所有n> 1的斐波那契數列。我有很多來自OOP的經驗,我不是那種在功能上用於編程的人。但是下面你會發現我的代碼的功能我想實現:關於實現函數計算斐波那契數列的問題

fib :: Int -> Int 
nextLast :: [Int]->Int 
insert' :: [Int]->[Int] 
retrieve :: [Int]->Int 
goThrough :: Int->[Int] 

fibl = [0,1] --List of edge cases to be used in the iteration 
nextLast a = a !! (length a - 2) 
insert' a = a ++ [last a + nextLast a] --How to create the pattern of Fibonacci series in a 

retrieve a = let a = insert' a 
      in last a 

goThrough n = replicate (n-1) 0 

fib 0 = 0 --Edge case #1 
fib 1 = 1 --Edge case #2 
fib n = let times = goThrough n --n>1, n = any natural number 
     in last [retrieve fibl | _<-times] 

我沒有得到編譯錯誤或類似的東西,但是當我運行這些代碼,然後什麼也沒有發生,它永遠不會終止。

有人可以解釋爲什麼發生這種情況,並最終建議解決這個問題?

在此先感謝!

+0

請注意'last [x | _ < - times]'將_always_或者'x'(或者如果'times'爲空則錯誤)。列表理解將建立一個重複相同元素的列表。在純粹的函數式編程中沒有任何狀態在進行,因此用相同的參數多次調用相同的函數沒有意義。 – chi

回答

4

定義

let a = insert' a 

是遞歸定義;右側的a指您正在定義的a

這裏是ghci中說:(交互式解釋是測試程序的小零件一個偉大的方式)

*Main> retrieve fibl 
*** Exception: <<loop>> 

嘗試

retrieve a = let b = insert' a 
      in last b 

還有其他的問題,你的程序一旦修復:

*Main> fib 1 
1 
*Main> fib 2 
1 
*Main> fib 3 
1 
*Main> fib 400 
1 

不看的權利,併爲這種行爲的線索是在這裏:

*Main> [retrieve fibl | _ <- goThrough 3] 
[1,1] 
*Main> [retrieve fibl | _ <- goThrough 6] 
[1,1,1,1,1] 

的理解[ x | _ <- goThrough n]創建與xn副本列表。
(這是不是很奇怪,因爲該元素不取決於值goThrough n,只有它的長度)。

恐怕沒有簡單的辦法解決這一點,因爲目前還不清楚代碼是如何打算上班。
我唯一的建議是停止循環思考。

+0

對不起,以前沒有回覆,我忘了:(無論如何,然後我已經使用函數的另一個實現來計算一些自然數的斐波那契數列,但我會嘗試在學校以外的我自己的實現上工作。出了問題,我會考慮他們:D – user2566415