composition function n times Haskell

Viewed 507

anyone knows how to create a function (addOne'') which do a given function (addOne') n times over itself (addOne')? basically f(f(x)) n times

addOne :: Int -> Int
addOne x = x*2

addOne' :: [Int] -> [Int]
addOne' [] = []
addOne' (x:xs) = addOne x : addOne' xs

addOne'' :: Int -> [Int] -> [Int]
addOne'' ????

so I want to do function addOne' over itself n times. Thanks!

4 Answers

If I understand correctly, you only need simple recursion. If you want to make this function yourself, here is a possible implementation :

recN :: (a -> a) -> Int -> (a -> a)
recN f n = recN_ f n
  where recN_ acc 1 = acc
        recN_ acc n_ = recN_ (f . acc) (n_ - 1)


-- usage : x4 is a function the multiply by 4, defined as (*2).(*2)
-- let x4 = recN (*2) 2 in x4 2
-- => 8

Notice that this solution uses a recursive subfunction with an accumulator. This is a common pattern in functional programming. Also, this function will run forever (or almost) if called with a negative or null 'n'. You can fix this situation using, for example, pattern guards instead of pattern match for the edge condition of the recursion.

Very short (n > 0)

reapply :: Int -> (a -> a) -> a -> a
reapply n f = foldr1 (.) $ replicate n f

Alternative (n >= 0)

reapply' :: Int -> (a -> a) -> a -> a
reapply' n f x = (iterate f x) !! n 

Point-free (n >= 0)

reapply'' :: Int -> (a -> a) -> a -> a
reapply'' n f = flip (!!) n . iterate f  

If anyone is looking for a succinct way to to write f ^ n, a function that applies f n times, here is one:

foldr (.) id (replicate n f)

For example, (+1) ^ n = (+n) is:

foldr (.) id (replicate n (+1))

Based on OP's comment below, OP may be interested in the iterate function, which repeatedly applies an argument to an initial value to create a list where each element documents the result at a certain step.

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

If you take the nth element of the resulting list, that will be the result when the function is applied n times.

iterate f x !! n == f . f .... f . f $ x
--                  '-- n times ---'
Related