Haskell中是否有一个库函数可以自己编写一个函数 n 次?
例如我有这个功能:
func :: a -> a
我想这样做:
func . func . func . func . func . func , ...
(最多 n 次,其中 n 仅在运行时已知)。
请注意,迭代函数不适合我正在做的事情,因为我不关心任何中间结果。
答案 0 :(得分:52)
iterate
解决方案没问题,或者您可能喜欢这个:n
f
份foldr (.) id (replicate n f)
的合成是{{1}}。
答案 1 :(得分:24)
\xs n -> iterate func xs !! n
我不知道为什么,但我觉得iterate
是人们在学习Haskell时不会经常接触到的东西。
如果您不喜欢!!
,那么您可以使用zip
和lookup
作为替代方案。 (某些人/组/工具不喜欢在某些情况下调用“错误”的函数,我并不认为在这些情况下查找更好)
lookup n . zip [0..] . iterate func
编辑:好的,所以我删除然后取消删除,因为我同意另一个回答者 - 你不应该因为它给你更多而忽略了对迭代的使用。
答案 2 :(得分:11)
答案 3 :(得分:10)
(\n -> appEndo . mconcat . replicate n . Endo) n f x
答案 4 :(得分:7)
我是Haskell的初学者,目前正在Learn You a Haskell For Great Good!的第5章(“高阶函数”),所以我还不熟悉之前回复中显示的函数。鉴于我到目前为止的理解,我会这样做:
applyNTimes :: Int -> (a -> a) -> a -> a
applyNTimes n f x
| n == 0 = x
| otherwise = f (applyNTimes (n-1) f x)
答案 5 :(得分:2)
trinithis' answer使用newtype包的变体,只是为了好玩:
(\n f -> under Endo (mconcat . replicate n) f)
或无点:
under Endo . (mconcat .) . replicate
答案 6 :(得分:2)
\n -> appEndo . foldMap Endo . replicate n
答案 7 :(得分:0)
iterate (f .) id !! n
或
iterate (f .) f !! (n-1)
取决于是否允许n == 0
。
答案 8 :(得分:0)
使用foldr
的另一种解决方案:
\n -> flip (foldr ($)) . replicate n
答案 9 :(得分:0)
这是一个复杂度为O(log n)而不是O(n)的版本(构建函数而不是应用函数):
composeN 0 f = id
composeN n f
| even n = g
| odd n = f . g
where g = g' . g'
g' = composeN (n `div` 2) f