user3236779
user3236779

Reputation: 83

Haskell perform function on list n number times

I am learning functional programming using Haskell. I am trying to create a function that takes a function f, and executes the function on some input x, n number of times.

(a -> a) -> a -> Int -> [a]
repeat f x n

So, the output list is like this:

[x, f(x), f(f(x)), ..., f^n(x)]

So far I have been able to come up with a function that I believe does this, but I don't know how to constrain it so it only performs n number of times:

fn f a = (f a) : (fn f (f a))

Could someone lend a hand? Thanks!

Upvotes: 1

Views: 266

Answers (2)

Meowcolm024
Meowcolm024

Reputation: 392

I'm here to give another way (just for fun).

There is a very similar function: scanl :: (b -> a -> b) -> b -> [a] -> [b] in the library, it performs:

scanl f z [x1, x2, ...] == [z, z `f` x1, (z `f` x1) `f` x2, ...]

which is quite similar to what you want to do. So we can write:

fn :: (a -> a) -> a -> Int -> [a]
fn f a n = scanl (\x _ -> f x) a (replicate n ())

-- or you can write:
-- fn f a n = scanl (const . f) a (replicate n ())

In (\x _ -> f x) we discard the second parameter (which is the ()).

Note how it works:

fn f a n == [a, (\x _ -> f x) a (), (\x _ -> f x) ((\x _ -> f x) a ()) (), ...]
         == [a, f a, f (f a), ...]

Upvotes: 0

Fyodor Soikin
Fyodor Soikin

Reputation: 80805

You just need to specify two separate cases: one where recursion happens and the list continues, and another where recursion does not happen, and there needs to be some way to decide between the cases. The third parameter n looks like just the right thing for that:

fn f a 0 = []
fn f a n = f a : fn f (f a) (n-1)

Upvotes: 3

Related Questions