Czy istnieje zwięzły, idiomatyczny sposób wyrażania function iteration? Oznacza to, że mając numer n
i funkcję f :: a -> a
, chciałbym wyrazić \x -> f(...(f(x))...)
, gdzie f
jest stosowany n
-razy.Jak zwięźle wyrażać iterację funkcji?
Oczywiście, mógłbym stworzyć dla niego własną funkcję rekursywną, ale byłbym zainteresowany, jeśli istnieje sposób na szybkie wyrażenie tego przy użyciu istniejących narzędzi lub bibliotek.
tej pory mam te pomysły:
\n f x -> foldr (const f) x [1..n]
\n -> appEndo . mconcat . replicate n . Endo
ale wszystkie one korzystać z list pośrednie i nie są bardzo zwięzłe.
Najkrótsza jeden znalazłem do tej pory używa półgrup:
\n f -> appEndo . times1p (n - 1) . Endo
,
ale działa tylko dla liczb dodatnich (nie na 0).
Przede wszystkim koncentruję się na rozwiązaniach w Haskell, ale chciałbym także zainteresować się rozwiązaniami Scala lub nawet innymi językami funkcjonalnymi.
Coś za pomocą 'iterate', może? – pigworker
@pigworker iterate wygląda dobrze. '\ n f x -> iteruj f x !! n' powinno działać. – tauli
'until ((<= 0). Snd) (\ (y, k) -> (f y, k-1)) (x, n)'. W tej chwili 'until' jest nadal rekursywny, więc nie będzie wstawiony, a nie będziesz miał rozpakowywania i wstawiania' f', ale w HEAD zostanie przekształcone opakowanie roboczy i gdy ta zmiana zostanie zwolniony, kompilator napisze dla ciebie pętlę. –