Reputation: 83
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
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
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