库函数用n次组成一个函数

时间:2010-10-12 01:13:40

标签: haskell

Haskell中是否有一个库函数可以自己编写一个函数 n 次?

例如我有这个功能:

func :: a -> a

我想这样做:

func . func . func . func . func . func , ... 

(最多 n 次,其中 n 仅在运行时已知)。

请注意,迭代函数不适合我正在做的事情,因为我不关心任何中间结果。

10 个答案:

答案 0 :(得分:52)

iterate解决方案没问题,或者您可能喜欢这个:n ffoldr (.) id (replicate n f)的合成是{{1}}。

答案 1 :(得分:24)

\xs n -> iterate func xs !! n

我不知道为什么,但我觉得iterate是人们在学习Haskell时不会经常接触到的东西。

如果您不喜欢!!,那么您可以使用ziplookup作为替代方案。 (某些人/组/工具不喜欢在某些情况下调用“错误”的函数,我并不认为在这些情况下查找更好)

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