Как вызвать ту же функцию "n" раз?

Возможный дубликат:
Функция библиотеки для создания самой функции n раз

Мне нужна функция для вызова другой функции n числа раз.

поэтому он будет выглядеть примерно так f n = g (g (g (g (l)))) где n равно числу функций g, вложенных.

Как мне это сделать? спасибо!

Ответ 1

iterate является общим решением:

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

Итак, если функция с областью совпадает с ее диапазоном, a -> a и начальным входом a, создайте бесконечный список результатов в форме:

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

И вы можете получить доступ к n-му элементу списка, используя !!:

iterate f a !! n

NB iterate f a !! 0 == a.

Ответ 2

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

Но более функциональным будет:

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

Это также можно сделать с помощью складок или морфизмов, но это легче понять.

Например, здесь, используя hylomorphism, но это не делает его более ясным:

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

В нем говорится что-то вроде compose (.) g (l), пока n == 0

Ответ 3

Это функция, которую я часто использую в приглашении ghci. Есть несколько способов написать его, ни одна из которых мне особенно нравится, но они все достаточно чисты:

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

Средние два обращаются ко мне, потому что мой мозг переключил foldr (.) id на "составление списка функций".

Мне просто хотелось бы, чтобы это было в прелюдии: -).

Ответ 4

Может быть сделано с помощью fold:

applyNTimes :: Int -> (a -> a) -> a -> a
applyNTimes n f val = foldl (\s e -> e s) val [f | x <- [1..n]]