A compact definition (that scales linear) is the following:
fib :: Num n => [n]
fib = 0 : nxt
    where nxt = 1 : zipWith (+) fib nxt
fibN :: Num n => Int -> [n]
fibN = flip take fib
What we here do is constructing a list fib that is "cons" of 0 and nxt (the rest of the lists). nxt is defined in the where clause as a "cons" of 1 and and the result of zipWith (+) fib nxt. The zipWith elementwise adds the elements of fib and nxt together, since nxt is always one element "ahead" of fib, we thus add the two last elements together. We then take the first n elements in the fibN function.
So we obtain a list like:
   fib          nxt
    |            |
    v            v
+-------+    +-------+    +-------------+
|  (:)  | ,->|  (:)  | ,->|   zipWith   |
+---+---+ |  +---+---+ |  +-----+---+---+
| 0 | o---'  | 1 | o---'  | (+) | o | o |
+---+---+    +---+---+    +-----+-|-+-|-+
  ^            ^                  |   |
  |            `------------------|---'
  `-------------------------------'
In case we thus evaluate up to the third element, this means that we call zipWith, and this will produce the sum of the head of fib and nxt and advance both points, like:
   fib          nxt
    |            |
    v            v
+-------+    +-------+    +-------+    +-------------+
|  (:)  | ,->|  (:)  | ,->|  (:)  | ,->|   zipWith   |
+---+---+ |  +---+---+ |  +---+---+ |  +-----+---+---+
| 0 | o---'  | 1 | o---'  | 1 | o---'  | (+) | o | o |
+---+---+    +---+---+    +---+---+    +-----+-|-+-|-+
               ^            ^                  |   |
               |            `------------------|---'
               `-------------------------------'
and so on.