2010-10-12 61 views
31

Haskell中是否有库函数可用于自己编写函数n次?库函数自己编写函数n次

比如我有这样的功能:

func :: a -> a 

,我想这样做:

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

(最多ñ次,其中ñ仅在运行时知道) 。

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

回答

49

iterate解决方案是好的,否则你可能会喜欢这一个:的n副本组成ffoldr (.) id (replicate n f)

+2

我喜欢这个,因为它也适用于n == 0。 – 2010-10-12 13:56:49

+5

@John其他解决方案(''''''''或'lookup.zip')也适用于n == 0.查看[iterate的定义](http://haskell.org/ghc/docs /6.12.1/html/libraries/base-4.2.0.0/src/GHC-List.html#iterate),你会看到它以基本情况开始列表。 – 2010-10-12 14:19:48

+0

@TomMD你是对的,我的错。我正在使用'iterate'来思考一个不同的定义,它不像你提供的那么好。 – 2010-10-12 17:08:42

24
\xs n -> iterate func xs !! n 

我不知道为什么,但我觉得iterate是人们并不一致地曝光学习Haskell时。

如果你不喜欢!!那么你可以使用ziplookup作为替代。 (有些人/组/工具不喜欢所谓的“错误”,在某些情况下的功能,我不主张查找在这些情况下更好)

lookup n . zip [0..] . iterate func 

编辑:好了,然后我删除未删除因为我同意其他回答者 - 你不应该因为它使更多比你需要的折扣使用迭代。

+2

由于'iterate'保证无限列表,所以我会使用'(!!)'或'genericIndex'来通过''''''''查找''''''。 – 2010-10-12 03:40:48

+0

是的,这就是我在这种情况下''lookup'和'zip'没有更好的结果。 '(!!)'有一个很像'头部'的烙印(或者,这是我的印象) – 2010-10-12 04:15:01

+8

是的,在我看来这也是一个当之无愧的耻辱,但它的真正含义是你必须小心使用它在可能不适用的情况下 - 并不是你永远不应该使用它。正如trinithis指出的那样,在这种情况下,除了传递负指数之外,它不会出错。顺便说一句!实际上这是一个比查找更好的选择:lookup和zip会永远循环到一个负向索引,寻找一个不存在的结果,但是!将立即失败,因为它知道指数不能是负数。 – mokus 2010-10-12 14:31:08

11

我不知道你为什么说iterate不合适。它完全适合这个目的。 (!! n) . iterate func的组成nfunc的副本。

(有人张贴了一个答案类似上面的代码,但他/她似乎已经删除了它。)

9

(\n -> appEndo . mconcat . replicate n . Endo) n f x

7

我在哈斯克尔初学者,目前的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) 
+4

我唯一不同的做法是模式匹配,而不是使用守卫:'applyNTimes 0 _ x = x'然后'applyNTimes n f x = f $ applyNTimes(n-1)f x'。实际上,你应该能够从中删除所有的x。 – MatrixFrog 2011-09-15 05:26:37

+0

这也是一个很好的解决方案,它应该提醒读者在[n]上通过归纳明确证明。 – 2011-09-15 05:26:43

+5

请注意,这比'|更好否则= applyNTimes(n-1)f(f x)',因为'f'可能是懒惰的。 – 2011-09-15 16:40:41

2

使用newtype包,只是为了好玩上trinithis' answer的变化:

(\n f -> under Endo (mconcat . replicate n) f) 

或无点:

under Endo . (mconcat .) . replicate 
+0

这是一个很酷的软件包。谢谢! – 2011-10-06 20:49:24

2
\n -> appEndo . foldMap Endo . replicate n 
0
iterate (f .) id !! n 

iterate (f .) f !! (n-1) 

取决于是否允许n == 0