iterate function not saving intermediate steps?
I just started learning Haskell, and as an exercise got into a Project Euler problem where Fibonacci numbers are summed. My current method is this function, which creates a new list with the next element:
fib :: (Integral a) => [a] -> [a]
fib xs@(x1:x2:_) = (x1+x2) : xs
I found the function iterate
which reapplies the function on it's result. However, the result is a list of lists, [[2,1],[3,2,1],[5,3,2,1],..]
. What is the alternative to iterate
when I'm not interested in the intermediate results? I want to do a takeWhile
with a condition on the last generated number. Is this the wrong way to think about it altogether?
(I've seen better/shorter/niftier ways of generating the Fibonacci sequence, so I'm not really looking for feedback on the fib
function - but I'd like to make it work, suboptimal method o开发者_如何学Gor not)
Just use iterate
! Because Haskell is a pure language, all of the sublists get shared and you pay essentially no cost for having generated all of those mini lists: [2, 1]
is actually the 2, 1
in [3, 2, 1]
, and so forth.
You don't really want a takeWhile
, because that will give you a lot of extra gunk and you'll still need to get to the end of the list with last
. Instead, use find
.
Also note that if you're planning on summing the resulting list, you've missed a 1
so you'll be one off.
I'm not sure about the use of iterate
, but see Filtering fibonacci sequence in Haskell for how to filter a list of fibs.
Is this the same homework assignment?
I would use "take", since each successive approximation will be one integer more accurate than the last. You can then do (head . reverse) on that.
Note that "every" result is an intermediate result if the function you are iterating doesn't have a computable fixed point.
When needing a function in Haskell just define it :)
The folowing isn't the most elegant or idiomatic Haskell, but serves to show that you can always do things by hand with a tail recursive loop if the need arises
apply_n f n x =
if n = 0 then x
else apply_n' f (n-1) (f x)
n_th_fib n = apply_n fib n [1,1]
I'm pretty sure there is a neater way to do this using folds (or a library function I forgot about :) )
精彩评论