Как вызвать ту же функцию "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]]