The reason your version is very slow is because there are no notes for the parts lucas (n-1) and lucas (n-2) - so both values ββwill be recalculated (recursively) again and again, which is very slow.
The solution is to save the calculated values ββsomewhere:
using list-lazyness
Here is a simple version that will do the same as your code snippet, but should be faster - it will save the already calculated parts in the list itself:
lucasNumbers :: [Integer] lucasNumbers = 1:3:zipWith (+) lucasNumbers (tail lucasNumbers) first50 :: [Integer] first50 = take 50 lucasNumbers
the reason this happens faster is because now the laziness of the list will help you remember the different parts
You can learn a lot about this if you are looking for Fibonacci sequences in Haskell (this is really the same as yours;))
using unfoldr
another (possibly less magical) way to do this is with Data.List.unfoldr - here the already calculated parts (or those that matter - the last and second-last elements) will be in the state that you pass for the expand operation:
lucasNumbers :: [Integer] lucasNumbers = unfoldr (\ (n,n') -> Just (n, (n',n+n'))) (1,3)
to your comment / question:
Assuming you are talking about x(n) = x(n-1)^2-2 , you can do it like this:
lucasLehmer :: [Integer] lucasLehmer = 4 : map (\ x -> x^2-2) lucasLehmer
which will give something like this:
Ξ»> take 5 lucasLehmer [4,14,194,37634,1416317954]
Maybe you should try the unfoldr version.