35

Possible Duplicate:
Library function to compose a function with itself n times

I need a function to call another function n number of times.

so it would look something like this f n = g(g(g(g(l)))) where n equals to the number of function g nested.

how should I go about this? thanks!

Community
  • 1
  • 1
phxxx
  • 361
  • 1
  • 3
  • 3
  • http://stackoverflow.com/q/3911060/465466 – Tsuyoshi Ito Sep 14 '11 at 21:44
  • This really is a repeat of the question Tsuyoshi linked to. Should this one be closed then? – Davorak Sep 14 '11 at 22:05
  • 1
    Davorak: But this way I get double the points for the same answer. Seriously though, I forgot about that previous question. Perhaps SO should have a better filter process for repeat questions - we've been getting a lot of those lately and they really don't add any value. – Thomas M. DuBuisson Sep 14 '11 at 22:12

4 Answers4

83

iterate is a common solution:

> :t iterate
iterate :: (a -> a) -> a -> [a]

So, given a function with a domain the same as its range, a -> a, and an initial input a, produce an infinite list of results in the form:

iterate f a --> [a, f(a), f(f(a)), ...]

And you can access the nth element of the list using !!:

iterate f a !! n

NB iterate f a !! 0 == a.

Thomas M. DuBuisson
  • 64,245
  • 7
  • 109
  • 166
11

This is a function that I use often at the ghci prompt. There are a few ways to write it, none of which I am particularly fond of, but they are all reasonably clean:

fpow n f x = iterate f x !! n

fpow n f = foldr (.) id $ replicate n f

fpow n = foldr (.) id . replicate n   -- just eta the above

fpow 0 f = id
fpow n f = f . fpow (n-1) f

The middle two appeal to me because my brain has chunked foldr (.) id to mean "compose a list of functions".

I kinda just wish it were in the prelude :-).

luqui
  • 59,485
  • 12
  • 145
  • 204
  • 1
    I randomly thought of [`compose2`](http://stackoverflow.com/questions/5821089/haskell-function-composition-operator-of-type-cd-abc-abd/5822800#5822800), or `(.*) = (.) . (.)`, which allows you to write it pointlessly: `fpow = foldr (.) id .* replicate` – Dan Burton Sep 15 '11 at 02:47
7
f 0 = l
f n = g (f (n-1))

But more functional would be:

f 0 l = l
f n l = g (f (n-1) l)

This could also be done with folds or morfisms, but this is easier to understand.

For example here's using a hylomorphism, but it doesn't make it clearer really:

f g l = hylo l (.) (\n -> (g, n-1)) (==0)

It says some thing like compose (.) g(l) until n==0

nulvinge
  • 1,600
  • 8
  • 17
4

Can be done using fold:

applyNTimes :: Int -> (a -> a) -> a -> a
applyNTimes n f val = foldl (\s e -> e s) val [f | x <- [1..n]]
Ankur
  • 33,367
  • 2
  • 46
  • 72