fibs :: [Int]
fibs = 0 : 1 : [ a + b | (a, b) <- zip fibs (tail fibs)]
This generates the Fibonacci sequence.
I understand the behaviour of the guards, of :, zip and tail, but I don't understand <-. What is it doing here?
Due to the upvotes I made my comment into an answer.
What you see is not a guard but it is list comprehension. For starters think of it as a way to express a mathematical set notation like A = { x | x element N } which means something along the lines of: The set A is the set of all natural numbers. In list comprehension that would be [x | x <- [1..] ].
You can also use constraints on your numbers: [x | x <- [1..], x `mod` 2 == 0 ] and many other things.
There are alot of good haskell turorials out there that cover list comprehension and even a StackOverflow question regarding haskell resources.
The only tricky thing is the zip fibs (tail fibs). zip just makes a pairwise list from each of its arguments. So if you have two lists like this:
[ 1, 2, 3, 4 ]
[ "a", "b", "c", "d" ]
Zipping them will make:
[ (1,"a"), (2,"b"), (3,"c"), (4,"d") ]
The left arrow (assignment into a destructuring pattern) just extracts the paired elements so they can be added together. The two lists being zipped are fibs and (tail fibs) -- in other words, the Fibonacci sequence, and the Fibonacci sequence offset by 1 element. Haskell is lazily-evaluated, so it can calculate the list to however many elements are required. This applies to zip as well.
One advantage of functional programming is that you can evaluate an expression by hand like it is a math problem:
fibs = 0 : 1 : [ a + b | (a, b) <- zip fibs (tail fibs)]
= 0 : 1 : [ a + b | (a, b) <- zip [0, 1, ??] (tail [0, 1, ??])]
Here the ?? is the part which has not yet been evaluated. We will fill it in as we proceed.
= 0 : 1 : [ a + b | (a, b) <- zip [0, 1, ??] [1, ??])]
= 0 : 1 : [ a + b | (a, b) <- (0, 1) : zip [1, ??] [??]]
Note that I am eliding the evaluation of zip since its definition is not given here and the details are not really germane to the current question. This is the notation I will use to show each pair of numbers is created by zip and consumed by the list comprehension.
= 0 : 1 : 0+1 : [ a + b | (a, b) <- zip [1, ??] [??]]
= 0 : 1 : 1 : [ a + b | (a, b) <- zip [1, ??] [??]]
Now we know that the next element in the ?? is a 1:
= 0 : 1 : 1 : [ a + b | (a, b) <- zip [1, 1, ??] [1, ??]]
= 0 : 1 : 1 : [ a + b | (a, b) <- (1, 1) : zip [1, ??] [??]]
= 0 : 1 : 1 : 1+1 : [ a + b | (a, b) <- zip [1, ??] [??]]
= 0 : 1 : 1 : 2 : [ a + b | (a, b) <- zip [1, ??] [??]]
And the next element is a 2:
= 0 : 1 : 1 : 2 : [ a + b | (a, b) <- zip [1, 2, ??] [2, ??]]
Rinse and repeat.
Let's expand it out.
zip creates pairs out of the contents of two lists. So the first pair zip fibs (tail fibs) gives us is (0, 1), which adds up to 1. So now the list is [0,1,1]. We now know three elements in the list, so the list comprehension can continue, grabbing the next item from the list and the next item from the tail, which gives (1,1) — added together, making 2. Then we get the next pair, which is (1,2), making the next number in the sequence 3. This can continue infinitely, since the comprehension will always provide enough items.
For what it's worth, I find the following version easier to understand:
fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
The list comprehension in the brackets:
[ a + b | (a, b) <- zip fibs (tail fibs)]
returns a list containing the output (a + b) where the variables a and b come from the result of
zip fibs (tail fibs)
The key concept here is lazy evaluation which means that if the value is right there then take it without further computing say that i have got the value and the job is done, i don't need to compute future value temporary now. and if the value is not available then just compute it and of course it's lazy so it won't bother computing next needed value.
i write another implementation to illustrate this and use ?? to be a value placeholder which needs to be computed if needed.
fibs = 1:1:[ y!!1 + y!!0 | x<-[2..], y <- [[last (take x fibs), last (take (x-1) fibs)]] ]
i use x to indicate number of available values in fibs (which doesn't need to be computed again) and y to be a [[last fib values]] nested list. its inner list contains last two values of available values in fibs.
so here is the process of the computation:
x == 2, so y is [last (take 2 fibs), last (take 1 fibs)]. lazy evaluation lets us just take available values and don't bother worrying values in the future. it tells me to take first 2 and 1 values of fibs and the values are right there 1,1 and 1. y now is [last [1,1], last [1]] which is [1,1] and to get final value it need to compute y!!1 + y!!0. That's obvious and final value is 2. so now fibs is [1, 1, 2, ??].
x == 3, just the same as step 1. y is [last [take 3 fibs], last [take 2 fibs]] which is [last [1,1,2], last [1,1]], the value now is available so we can just take it and go on. Finally, we got the fourth value 3.
that's it, just repeat the above steps and you can get all values even it is infinite
Doesn't it seems familiar? just like using a recursive function to compute fibs. we now let compiler itself to do the stuff(referring). we use the lazy evaluation here.
the zip implementation is just another representation of [last fibs values] here. you just need a little modification to understand the zip version of fibs implementation.
haskell wiki: lazy evaluation
for <- symbol: List comprehension
I prefer the more general
fib = 1 : [ x + y | (x, y) <- zip fib (0 : fib) ]
This most closely models how one understands the Fibonacci sequence in terms of generating functions. If f(n) = 0 for n < 0, f(0) = 1, and f(n) = a*f(n-1) + b*f(n-2) for n > 0, then we'd like to be able to write the single line
f(n) = 1_0 + a*f(n-1) + b*f(n-2)
and have the reader know what we mean. Unfortunately, this requires some unstated conventions to make sense.
Using the generating function g(t) = f(0) + f(1)t + f(2)t^2 + ... we can write the equation
g(t) = 1 + a t g(t) + b t^2 g(t)
which easily solves for g(t) in closed form as
g(t) = 1 / (1 - a t - b t^2)
The Haskell code
g = 1 : [ a*x + b*y | (x, y) <- zip g (0 : g) ]
implements this same equation.
It defines this stream diagram,(*)
.---->>---->>----.
/ \
<---- 0 <---- 1 ----<<--- (+)
\ /
*--->>---*
that pulls new input from itself as it is produced, but always by one and two positions behind the production point, maintaining the two "back pointers" into the sequence as it were, one position apart.
This is reflected in the definition,
-- .------->>------>>---.
-- / \
fibs = 0 : 1 : [ a + b | a <- fibs
{- \ -} | b <- tail fibs]
-- \ /
-- *-->>------>>---*
with parallel list comprehensions (:set -XParallelListComp etc.).
Since it only uses its last two elements, it is equivalent to
map fst . iterate (\(a, b) -> (b, a+b)) $ (0,1)
(*) The execution of this diagram proceeds as follows:
.---->>---->>----.
/ \ 0
? <---- 0 <---- 1 ----<<--- (+)
\ / 1
*--->>---*
.---->>---->>----.
/ \ 1
0,? <---- 1 <---- 1 ----<<--- (+)
\ / 1
*--->>---*
.---->>---->>----.
/ \ 1
0,1,? <---- 1 <---- 2 ----<<--- (+)
\ / 2
*--->>---*
.--->>---->>----.
/ \ 2
0,1,1,? <--- 2 <--- 3 ----<<--- (+)
\ / 3
*--->>---*
.--->>--->>---.
/ \ 3
0,1,1,2,? <--- 3 <-- 5 ---<<--- (+)
\ / 5
*--->>---*
......
Related
This question already has answers here:
Understanding Haskell's fibonacci
(9 answers)
Closed 5 years ago.
this one:
fib = 1 : 1 : [a + b | (a, b) <- zip fib (tail fib)]
i understand that at first fib is [1, 1, ..]
(.. = rest of the list)
so here fib = [1, 1, ..] and tail fib = [1, ..] so (a, b) is (1, 1) which translate to a + b which is 2 and now the list looks like that:
fib = 1 : 1 : 2 : [a + b | (a, b) <- zip fib (tail fib)]
and here i get confused:
now i think fib is [1, 1, 2, ..] and tail fib is [1, 2, ..]
and if i zip the lists, i again should get that a + b is 1 + 1 because those are still the first elements of the two lists.
where am i wrong here?
(i know i am but i can't understand why and what is going on here)
You are correct that
fib = 1 : 1 : [a + b | (a, b) <- zip fib (tail fib)]
produces the next element to be 2. However, fib = 1 : 1 : 2 : [a + b | (a, b) <- zip fib (tail fib)] is not accurate for the next step. Since you evaluate zip fib (tail fib) on this step, it must be substituted from its definition, not left as it is. A more accurate formula looks something like:
fib = 1 : 1 : 2 : [a + b | (a, b) <- zip (tail fib) (tail (tail fib)]
One way to think of the evaluation of zip is that each application consumes the next two head elements of each of the given lists. In this case, the next iteration will return (a, b) = (1, 2) since this is the next pair of numbers in fib and (tail fib) respectively.
I am overall confused, and looking for a very detailed and explanatory answer, of how this code works:
let xs = [1] ++ concatMap (\x -> [x+1,x*10]) xs in xs
How does concatMap know what to map and concat over?
I understand more basic examples:
let x = [1] ++ x
Here it gets evaluated like [1] ++ [1] ++ [1] ..
But I don't seem to understand the first example with concatMap. It just doesn't make sense to me. I can work with recursion frequently without problems. However, that one piece of code is very confusing.
Let's try a much simpler example:
let xs = 1 : xs in xs
OK, so xs points to a (:) node. The head-pointer from here points to 1, and the tail-pointer points to xs (i.e., back to itself). So this is either a circular list, or an infinite list. (Haskell regards the two as the same thing.) So far, so good.
Now, let's try a harder example:
let xs = 1 : map (+1) xs in xs
Do you know what this will do?
So xs points to a (:) node. The head-pointer points to 1. The tail-pointer points to the expression map (+1) xs, with xs pointing back to the top again.
If you try to "look at" the contents of this list, it will cause the map expression to start executing. The definition of map is
map f js =
case js of
k:ks -> (f k) : (map f ks)
[] -> []
So map looks at xs to see if it's [] or (:). As we know, it's (:). So the first pattern applies.
What this means is that the entire map (+1) xs expression gets overwritten with (:), with its head-pointer pointing to (+1) 1 and its tail-pointer pointing to map (+1) xs2 (with xs2 denoting a pointer to the tail of xs).
At this point, inspecting (+1) 1 turns it into 2. So now we basically have
xs = 1 : 2 : map (+1) xs2
^ |
|___________|
This cycle repeats as you examine the list. Critically, at every moment map is pointing to a node just before itself. If it ever caught up to itself, you would have a problem. But map only ever looks at nodes we've already calculated, so it's fine.
The net result, then, is xs = 1 : 2 : 3 : 4 : ...
If you can understand that, you ought to be able to understand your own more complicated example.
If you want to make your head hurt, try:
fibs = 1 : 1 : zipWith (+) fibs (tail fibs)
This is a standard Haskell incantation for spitting out the Fibonacci numbers in O(N) time (rather than O(N*N) as the more obvious recursion would give you).
Think of concatMap as a simple composition of concat and map (concat . map).
In this particular case, you are initializing xs with 1. Once you start running your map, it will lift the lambda to operate on 1 (the first position in the list) and create a list containing two values, 2 and 10. Concat just extracts those two values from that list and puts them naked in xs, concatenating them with the existing 1. At this point, xs contains 1, 2 and 10 (xs = [1,2,10]).
Now, xs contains 1, 2 and 10 and map will repeat the process (of course, starting from the second position in the list), now operating on 2 and creating a list containing 3 and 20 and a second list containing 11 and 100 when operating on 10 (third position in the list). Concat will now extract those 4 values and append them to the contents of xs. Now xs contains 1, 2, 10, 3, 20, 11 and 100 (xs = [1,2,10,3,20,11,100]).
And you can rinse and repeat, this time map operating on the fourth position in the list (and every subsequent position), and concat doing its work to remove the new list containers and place the values directly into the top level list. As you can see, this process will generate that infinite list.
Does this help?
First, what is concat? It concatenates lists, presented to it in a list:
concat [ [1], [2], [3] ] = [ 1, 2, 3 ]
concat [ [1], [2,22], [3] ] = [ 1, 2, 22, 3 ]
and so forth. What does map do? It transforms each element in a list it is presented with:
map (1+) [1, 2, 3] = [ 2, 3, 4 ]
map (:[]) [1, 2, 3] = [ [1], [2], [3] ]
map (\x-> [x+1, x*10]) [1, 2, 3] = [ [2,10], [3,20], [4,30] ]
But concatMap f xs is the same as concat (map f xs):
concatMap (\x-> [x+1, x*10]) [1, 2, 3]
= concat (map (\x-> [x+1, x*10]) [1, 2, 3])
= concat [ [2,10], [3,20], [4,30] ]
= [ 2,10, 3,20, 4,30 ]
But, it doesn't need to see the input list through to its end, in order to proceed, producing its elements one by one. This is because of Haskell's laziness. Simply,
concat [ [2,10], [3,20], [4,30] ]
= [ 2,10, 3,20, 4,30 ]
= [ 2,10] ++ concat [ [3,20], [4,30] ]
This means that actually,
concat xs == foldr (++) [] xs
-- concat [a,b,...,n] = a ++ (b ++ (... ++ (n++[])...))
and
concatMap f xs == foldr ((++).f) [] xs
-- concatMap f [a,b,...,n] = f a ++ (f b ++ (... ++ (f n++[])...))
so it does work incrementally. For your example,
let xs = [1] ++ concatMap (\x -> [x+1,x*10]) xs in xs
== let xs = [1] ++ foldr ((++).(\x -> [x+1,x*10])) [] xs in xs
== let xs = [1] ++ foldr (\x -> ([x+1,x*10] ++)) [] xs in xs
== let xs = [1] ++ foldr (\x r -> x+1 : x*10 : r) [] xs in xs
Which simply means: xs is a list, which contains 1, and then x+1 and x*10 for each element x in xs - from the start again. We could write this down also as
xs = 1 : [y | x <- xs, y <- [x+1, x*10]]
So for 1, 2 and 10 will be "appended" at list's end, then for 2, 3 and 20 will be produced, for 10 - 11 and 100, and so on:
xs = 1 a b c d e f g h ....
[2,10]=[a,b]
= 1 2 10 c d e f g h ....
[3,20]=[c,d]
= 1 2 10 3 20 e f g h ....
[11,100]=[e,f]
....
Of course this won't be evaluated on its own; the definition is "dormant" until used, e.g. to print the first 6 elements of xs:
Prelude> let xs = 1 : [y | x <- xs, y <- [x+1, x*10]]
Prelude> take 6 xs
[1,2,10,3,20,11]
As we can see, what's really been defined here is not an infinite list - there are no infinite things after all - but a process of calculating as much of its elements as might be needed.
Yet another way of writing this definition is
xs = 1 : next xs
where
next (x:xs) = x+1 : x*10 : next xs
where the computation's structure is seen yet clearer: next "looks back" into xs as it is being defined, first 1 notch back; then 2; then 3; etc. (because it produces two new list elements for each one it consumes; this definition is thus productive). This is characteristic of a "corecursive" definition. Its calculation proceeds as
take 6 xs
= take 6 xs where xs=1:next xs -- next looks 1 element back
= 1:take 5 xs1 where xs=1:xs1; xs1=next xs
= 1:take 5 xs1 where xs1=2:10:next xs1 -- 2 elements back
= 1:2:take 4 xs2 where xs1=2:xs2; xs2=10:next xs1
= 1:2:10:take 3 xs3 where xs1=2:xs2; xs2=10:xs3; xs3=next xs1
= 1:2:10:take 3 xs3 where xs2=10:xs3; xs3=3:20:next xs2 -- 3 elements
= 1:2:10:3:take 2 xs4 where xs2=10:xs3; xs3=3:xs4; xs4=20:next xs2
= 1:2:10:3:20:take 1 xs5 where xs2=10:xs3; xs3=3:xs4; xs4=20:xs5; xs5=next xs2
= 1:2:10:3:20:take 1 xs5 where xs3=3:xs4; xs4=20:xs5; xs5=11:100:next xs3 -- 4
....
I'm new to Haskell and I really need some help!
I have to write a program that includes a recursive function to produce a list of binomial coefficients for the power n=12 using the Pascal's triangle technique.
I have some ideas in my head but because I'm just getting started I have no idea how to implement this to haskell?!
Could someone please help me out??
first row: (a+b)^0 = 1
second row: (a+b)^1 = 1a+1b
third row: (a+b)^2 = 1a^2+2ab+1b^2
and so on...this is my main idea. But I cant even try this out because I have no idea how I put this in Haskell..getting errors all the time
Start by assigning an index to each element in the triangle:
| 0 1 2 3 4 5 6
--+--------------------------
0 | 1
1 | 1 1
2 | 1 2 1
3 | 1 3 3 1
4 | 1 4 6 4 1
5 | 1 5 10 10 5 1
6 | 1 6 15 20 15 6 1
Here I've simply put the triangle on its side so that we can number them. So here I'd say that the element at (6, 4) is 15, whereas (4, 6) doesn't exist. Now focus on writing a function
pascal :: Integer -> Integer -> Integer
pascal x y = ???
Such that you can generate this version of the triangle. You can start by writing
pascal x y
| x == 0 = 1
| x == y = 1
| x < y = error "Not a valid coordinate for Pascal's triangle."
| otherwise = pascal ? ? + pascal ? ?
Note that here, instead of figuring out which elements should be added together by diagonals, you can do it via rectangular coordinates. Here, you'll note that y is which row in the triangle you're on and x is the position of the element in that row. All you need to do is figure out what goes in place of the ?s.
Once you get that working, I've got a one-liner for this triangle that is more efficient and can generate the entire triangle all at once while still using recursion:
import Data.List (scanl1)
pascals :: [[Integer]]
pascals = repeat 1 : map (scanl1 (+)) pascals
Don't try turning this solution in to your professor, it's not what they're looking for and it would make it pretty obvious someone gave you this solution if you've only been doing Haskell for a week. However, it really shows how powerful Haskell can be for this sort of problem. I would show how to index pascals to get a given (n, k) value, but doing so would also give you too many hints for solving the naive recursion.
Since there's been some confusion, the reason why I gave this solution is to draw a parallel between it and the often shown lazy implementation for the Fibonacci sequence:
fibs = 1 : 1 : zipWith (+) fibs (tail fibs)
Compared to
fib 0 = 1
fib 1 = 1
fib n = fib (n - 1) + fib (n - 2)
This definition generates an infinite list of all the Fibonacci numbers, and does so quite efficiently (from the point of view of the CPU, RAM is a different story). It encodes in its first 2 elements the base case, then a recursive expression that can calculate the rest. For the Fibonaccis, you need 2 values to start you off, but for Pascal's triangle, you only need one value, that value just happens to be an infinite list. There is an easy to see pattern going across the columns in the grid I posted above, the scanl1 (+) function just takes advantage of this pattern and allows us to generate it very easily, but this is generating the diagonals of the triangle rather than the rows. To get the rows, you can index this list, or you can do some fancy tricks with take, drop, and other such functions, but that's an exercise for another day.
Start out with the triangle itself:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
...
You should notice that to write down the next row, you must apply this rule: sum the previous rows' adjacent elements, using a 0 for the lonely edge elements. Visually:
0 1 0
\+/ \+/
0 1 1 0
\+/ \+/ \+/
0 1 2 1 0
\+/ \+/ \+/ \+/
1 3 3 1
...
Operationally, that looks like this:
For row 0:
[1] (it's a given; i.e. base case)
For row 1:
[0, 1] <- row 0 with a zero prepended ([0] ++ row 0)
+ +
[1, 0] <- row 0 with a zero appended (row 0 ++ [0])
= =
[1, 1] <- element-wise addition
For row 2:
[0, 1, 1]
+ + +
[1, 1, 0]
= = =
[1, 2, 1]
Generally, for row N:
element-wise addition of:
[0] ++ row(N-1)
row(N-1) ++ [0]
Remember that element-wise addition of lists in Haskell is zipWith (+).
Thus we arrive at the following Haskell definition:
pascal 0 = [1]
pascal n = zipWith (+) ([0] ++ pascal (n-1)) (pascal (n-1) ++ [0])
Or in a fashion similar to the famous "lazy fibs":
pascals = [1] : map (\xs -> zipWith (+) ([0] ++ xs) (xs ++ [0])) pascals
Another possible solution (more suitable for beginners in my opinion):
pascal :: Integer -> [Integer]
pascal 0 = [1]
pascal 1 = [1, 1]
pascal n = let p = pascal (n - 1)
in [1] ++ pascalStep p ++ [1]
pascalStep :: [Integer] -> [Integer]
pascalStep [] = []
pascalStep [_] = []
pascalStep (x:y:xs) = x + y : pascalStep (y : xs)
Using let to avoid more space usage.
pascal is calling recursively to find all previous rows, using them to get the next row, until getting to the desired row.
Output:
*Main> pascal 3
[1,3,3,1]
*Main> pascal 4
[1,4,6,4,1]
*Main> pascal 5
[1,5,10,10,5,1]
Start with the base case.
pascal 0 0 = 1
Then handle the edge cases
pascal n 0 = 1
pascal n r | n == r = 1
Now expand with the recursive step
pascal n r = pascal (n - 1) (r - 1) + pascal (n - 1) r
If you want the list for a specific row, write a wrapper
binom n = map (pascal n) [0..n]
Figuring out the types shouldn't be hard
pascal :: Integral a => a -> a -> a
binom :: Integral a => a -> [a]
I'm on my phone so please excuse the mistakes, but you can use Haskell's lazy evaluation in a really cool way here.
pascals :: [[Int]]
pascals = [1]:map (\r -> zipWith (+) (0:r) (r++[0])) pascals
Which you could make point free with a fork but it's rather esoteric.
pascals :: [[Int]]
pascals = [1]:map ((zipWith (+) -<) (0:) (++[0])) pascals
But I personally really like this code, and thinks it's worth being readable-
pascals :: [[Int]]
pascals = [1]:map next pascals
where next = (zipWith (+) -<) (0:) (++[0])
But combinators like that can get a bit confusing, no matter how much I like point free programming.
I have written the following code to generate a list containing the Fibonacci numbers.
fibonacci = [a + b | a <- 1:fibonacci, b <- 0:1:fibonacci]
I would expect the output of the list to be [1,2,3,5,8,13..], however, the output is not the Fibonacci sequence.
I can't quite understand why it doesn't work.
My reasoning is that, if the Fibonacci numbers are [1,2,3,5,8,13..] then this will be equal to the sum of the 2 lists [1,1,2,3,5,8,13..] and [0,1,1,2,3,5,8,13..], which are equivalent to 1:[1,2,3,5,8,13..] and 0:1:[1,2,3,5,8,13..] or 1:fibonacci and 0:1:fibonacci
I have looked up other ways of implementing this sequence, however I would really like to know why my code doesn't work.
The problem
With:
fibonacci = [a + b | a <- 1:fibonacci, b <- 0:1:fibonacci]
you are generating every possible combinations of the two lists. For example with:
x = [a + b | a <- [1, 2], b <- [3, 4]]
the result will be:
[1 + 3, 1 + 4, 2 + 3, 2 + 4]
Live demo
With zipWith
The closest you can get is with zipWith:
fibonacci :: [Int]
fibonacci = zipWith (+) (1:fibonacci) (0:1:fibonacci)
Live demo
List comprehensions model
Non-determinism
Cartesian products
Nested for-loops
which are all equivalent. So your Fibonacci sequence is wrong because it's computing way too many elements. In pseudocode it's a bit like
fibonacci =
for i in 1:fibonacci:
for j in 0:1:fibonacci:
i + j
What you really want is to zip the lists together, to perform computations in the order of the length of fibonacci instead of its square. To do that we can use zipWith and, with a little algebra, get the standard "tricky fibo"
fibonacci = zipWith (+) (1:fibonacci) (0:1:fibonacci)
fibonacci = zipWith (+) (0:1:fibonacci) (1:fibonacci) -- (+) is commutative
fibonacci = zipWith (+) (0:1:fibonacci) (tail (0:1:fibonacci)) -- def of tail
Then we just define
fibonacci' = 0:1:fibonacci
fibonacci' = 0:1:zipWith (+) (0:1:fibonacci) (tail (0:1:fibonacci))
fibonacci' = 0:1:zipWith (+) fibonacci' (tail fibonacci')
which is the standard with
fibonacci = drop 2 fibonacci'
You can also use the ParallelListComprehension extension which lets you do zipping in list comprehensions with a slightly different syntax
{-# ParallelListComp #-}
fibonacci = [a + b | a <- 1:fibonacci | b <- 0:1:fibonacci]
> take 10 fibonacci
[1,2,3,5,8,13,21,34,55,89]
List comprehensions don't work like that. You've written a nested traversal, whereas what you are trying to do is a zip.
To see the difference, consider:
Prelude> let fibs = [ a + b | (a,b) <- zip (1 : fibs) (0 : 1 : fibs) ]
Prelude> take 10 fibs
[1,2,3,5,8,13,21,34,55,89]
Which works as you'd expect.
There is a syntactic extension to Haskell that allows for parallel comprehensions, so the syntax does a zip for you. You can enable it with -XParallelListComp and then write:
Prelude> let fibs = [ a + b | a <- 1 : fibs | b <- 0 : 1 : fibs ]
Prelude> take 10 fibs
[1,2,3,5,8,13,21,34,55,89]
Another solution without zip or ParallelListComprehension is:
> fib = 0:1:[ last x + head y | x:y:[] <- [ [take i fib, drop i fib] | i <- [1,2..] ] ]
> take 10 fib
[0,1,1,2,3,5,8,13,21,34]
I've been trying to do an infinite list of powers the same as I done them like below, for a list of fibonacci numbers and factorials.
fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
facs = 1 : zipWith (*) [1 ..] facs
Thanks
Generating the powers of a number is as simple as using 'iterate':
iterate (*2) 1
To find a specific power (instead of listing them) it is faster to use (^). To see the individual steps of a large multiplication you can use scanl:
scanl (*) 1 [2, 3, 5, 7]
Finally to generate a list of all squares this is the approach I recommend:
fix (\more r s -> s : more (r + 1) (s + 2*r + 1)) 0 0
Or if you are uncomfortable with fix here are two alternative versions:
unfoldr (\(r, s) -> Just (s, (r + 1, s + 2*r + 1))) (0, 0)
map snd . iterate (\(r, s) -> (r + 1, s + 2*r + 1)) $ (0, 0)
For greater readability you can also use map:
List of consecutive powers of 2:
λ> map (2^) [0..10]
[1,2,4,8,16,32,64,128,256,512,1024]
Consecutive squares:
λ> map (^2) [0..10]
[0,1,4,9,16,25,36,49,64,81,100]
I think you can define an infinite sequence of the squares with just a list comprehension:
powers = [ ii*ii | ii <- [1 ..]]
take 10 powers
=> [1,4,9,16,25,36,49,64,81,100]
Edit: It's been explained that you are after the powers of 2, which can also be done with a list comprehension:
powersOf2 = [ 2^ii | ii <- [0 ..]]
take 10 powersOf2
=> [1,2,4,8,16,32,64,128,256,512]
You can extrapolate this to a generator function for any given base:
powersOfN nn = [ nn^ii | ii <- [0 ..]]
take 10 (powersOfN 3)
=> [1,3,9,27,81,243,729,2187,6561,19683]
take 10 (powersOfN 17)
=> [1,17,289,4913,83521,1419857,24137569,410338673,6975757441,118587876497]
powers n = 1 : map (n*) (powers n)
If you want an infinite list of power N by zipWith, this may be an easy way:
powersOfN :: [Integer]
powersOfN
= zipWith (^) [N,N..] [0,1..]
Here is an example of the power of 2:
Prelude> zipWith (^) [2,2..] [0,1..]
=>[1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576,2097152,4194304,8388608,16777216,33554432,67108864,134217728..]