How to define a list of recursive calls to a function in Haskell

I like your attempt

ls = 0 : f 0 : f (last ls)

These are the problems with it:

  • No type signature. Always write type signatures. They are technically speaking optional, but boy do they help to understand what's going on and what you even want.
  • You're trying to apply f directly to a list, but it's supposed to operate on list elements. (That's the cause of your error message.)
  • last on an infinite list can be no good. Anyways this is not what you want: f should be applied to all elements of the tail instead. That's what map is there for.

So, a correct and complete implementation of that attempt is the following:

iterate' :: (a -> a) -> a -> [a]
 -- altn.:  (Int->Int) -> [Int], without x₀ but always starting from 0
iterate' f x₀ = ls
 where ls = x₀ : f x₀ : map f (tail ls)

N.B. this doesn't actually give [f 0, f (f 0), f (f (f 0)) ..] but starts from 0. To start from f 0, simply remove the standalone x₀:

iterate' f x₀ = ls
 where ls = f x₀ : map f (tail ls)

...which doesn't terminate however (thanks @WillNess), because the tail would now recurse forever. But you don't actually need tail! This is the proper definition:

iterate' f x₀ = ls
 where ls = f x₀ : map f ls

If you want to define this yourself, vs use iterate as pointed out by @WillemVanOnsem, then simple primitive recursion is your friend:

f :: (a -> a) -> a -> [a]
f g x = let new = g x in new `seq` new : f g new

This is similar to iterate except that iterate starts with the element you provide (the first x) instead of the first application of the function:

iterate :: (a -> a) -> a -> [a]
iterate f x =  x : iterate f (f x)

A self-education can be acquired by hoogling for functions of this type and reading the implementation of any search hits found in the base package.


Haskell has already a function for that: iterate :: (a -> a) -> a -> [a]. For example:

Prelude> take 10 (iterate (2*) 1)
[1,2,4,8,16,32,64,128,256,512]

Your question is slightly different since the first element should be f 0, instead of 0, but we can simply apply f to it, or use tail :: [a] -> [a] on the result. For example:

ls :: Num a => (a -> a) -> [a]
ls = tail . flip iterate 0

For example:

Prelude> take 10 (ls (1+))
[1,2,3,4,5,6,7,8,9,10]