Generating the N-bonacci numbers I'm new to Haskell, and this is one of the more interesting programs I've made with it so far. I understand there are already solutions to this problem that use much less code, but to me this one seems fairly intuitive. Are there any ways I can improve this code to be more readable or efficient?
fib :: Int -&gt; [Integer]
fib n = (n-1) `replicate` 0 !: 1 ++ (+) `zipPoly` repFor tail (fib n) n
(!:) :: [x] -&gt; x -&gt; [x]
[] !: a = [a]
(l:ls) !: a = l : ls !: a
zipPoly :: (x -&gt; x -&gt; x) -&gt; [[x]] -&gt; [x]
zipPoly _ [] = []
zipPoly _ [a] = a
zipPoly f (a:b:c) = zipPoly f $ zipWith f a b : c
repFor :: (x -&gt; x) -&gt; x -&gt; Int -&gt; [x]
repFor _ _ 0 = []
repFor f a n = a : repFor f (f a) (n-1)
main = do
    s &lt;- getLine
    putStrLn &quot;Starting...&quot;
    putStr $ unlines $ map show $ fib (read s :: Int)

Explanations of functions:

fib n is a list containing the n-bonacci numbers, starting with n-1 zeros and then a one.
list !: elem concatenates elem to the end of list.
zipPoly func lists is equivalent to zipWith but with more than two lists.
repFor func start amount is a list of length amount where the first element is start and every element after it is func applied to the element before it  ([x, f x, f (f x), f (f (f x))...]).
Spacing! Separate function definitions with blank lines.
I'd use a, b, c for type variables and x, y, z for variables.
A . looks cleaner than a $.
putStr . unlines . map show . fib $ read s :: Int

I would add another pair of parentheses to make the order of application absolutely obvious.
(l:ls) !: a = l : (ls !: a)

For similar reasons, I prefer the following.
fib n = fibBase ++ zipPoly (+) fibTails
    where fibBase = replicate (n-1) 0 ++ [1]
          fibTails = repFor tail (fib n) n

I'd use cs for the remainder of the list instead of c. Perhaps a where helps, too.
zipPoly f (a:b:cs) = zipPoly f $ c:cs
    where c = zipWith f a b

zipPoly needs the associativity of f, if I'm not mistaken. Perhaps its worth a comment.
Perhaps use a fold?
zipPoly f [] = []
zipPoly f (xs:xss) = foldl (zipWith f) xs xss

Don't reinvent the wheel too much :). Use Hoogle to search for a function using its signature.
For example, !: is snoc. Since you only use it once, I'd replace it with a ++. Similarly, repFor f x0 n is take n . iterate f $ x0.