Possible Solution:
> import Data.Monoid > import Debug.SimpleReflect -- not really needed, just for showing the result > (appEndo . mconcat . replicate 5 . Endo $ f) a f (f (f (f (fa))))
Other (already mentioned):
> iterate fa !! 5 f (f (f (f (fa))))
(add lambdas if you want to turn it into a function)
However, do not forget that Haskell is lazy: the above methods will first build a thunk by adding f many times and only then start evaluating. Sometimes f could be repeated in constant space, for example. when f :: Int -> Int (and f itself works in constant space), but the above approaches work only in linear space.
I would define using my own line iterator combinator, for example:
iter :: Int -> (a -> a) -> a -> a iter 0 _ x = x iter nfx = iter (pred n) f $! fx
or even,
iter nfx = foldl' (flip $ const f) x [1..n]
which is more of a translation by Haskell of what has already been posted in the question.
Alternatively, we can define a strict version of iterate (which IMHO must already exist ...)
iterate' :: (a -> a) -> a -> [a] iterate' fx = x : (iterate' f $! fx)
source share