Reputation: 85
I have problems with implementing a function that calculates Fibonacci series for all n>1 with list comprehensions. I have a lot of experience from OOP and I am not that used with programming functionally. But below you'll find my codes to the function I am trying to implement:
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]
I don't get compile errors or something like that, but when I run these codes, then nothing happens and it never terminates.
Can someone explain why this happens and, eventually, recommend a solution to the problem?
Thanks in advance!
Upvotes: 0
Views: 105
Reputation: 66371
The definition
let a = insert' a
is a recursive definition; the a
on the right hand side refers to the a
you're defining.
Here's what ghci says:
*Main> retrieve fibl
*** Exception: <<loop>>
(The interactive interpreter is a great way to test small parts of a program.)
Try
retrieve a = let b = insert' a
in last b
There are other problems with your program once you fix that:
*Main> fib 1
1
*Main> fib 2
1
*Main> fib 3
1
*Main> fib 400
1
doesn't look right, and a clue for this behaviour is here:
*Main> [retrieve fibl | _ <- goThrough 3]
[1,1]
*Main> [retrieve fibl | _ <- goThrough 6]
[1,1,1,1,1]
The comprehension [ x | _ <- goThrough n]
creates a list with n
copies of x
.
(This isn't very surprising as the elements don't depend on the values in goThrough n
, only its length.)
I'm afraid there's no easy fix for this, as it's unclear how the code is intended to work.
My only advice would be to stop thinking in terms of loops.
Upvotes: 4