Возможным решения:
> 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 (f a))))
Другой (уже упоминалось):
> iterate f a !! 5
f (f (f (f (f a))))
(добавить лямбды, если вы хотите, чтобы превратить его в функцию)
Однако, не забывайте, что Haskell ленив: вышеуказанные методы сначала построить преобразователь, применяя f
много раз, и только после этого приступить к оценке. Иногда f
может быть итерирован в постоянном пространстве, например. когда f :: Int -> Int
(и f
сам работает в постоянном пространстве), но приведенные выше подходы работают только в линейном пространстве.
Я бы определил собственной строгой итерации комбинатора, например .:
iter :: Int -> (a -> a) -> a -> a
iter 0 _ x = x
iter n f x = iter (pred n) f $! f x
или даже
iter n f x = foldl' (flip $ const f) x [1..n]
который более менее в Haskell перевод того, что было уже размещены в этом вопросе.
В качестве альтернативы, можно можно определить строгую версию iterate
(что ИМХО должно уже существовать ...)
iterate' :: (a -> a) -> a -> [a]
iterate' f x = x : (iterate' f $! f x)
может один из downvoters, пожалуйста, объясните, в чем проблема здесь? Вопрос мне кажется хорошим. FP subcommunities здесь, как правило, очень дружелюбны, и я надеюсь, что мы сможем сохранить его таким образом, поэтому, пожалуйста, по крайней мере, почему ваш вопрос плох, по вашему мнению. – Carsten
Я думаю, что вы должны опубликовать один вопрос на каждый язык, поскольку будущие люди, вероятно, будут искать один ответ. В основном, я бы сказал, если ваш вопрос ожидает разные ответы, тогда вы должны разделить его. – PatJ
@Carsten Уровни шума умеренности, по-видимому, выше, чем обычно на данный момент. За последние пару дней я видел не только нечетные downvotes, но и абсурдные закрытые голоса по меньшей мере в двух вопросах [haskell]. – duplode