有趣的是Reduce
不起作用......请注意,“手动减少”有效:
f <- function(x) x^2
g <- function(x) x^3
h <- function(x) x^4
x <- runif(3)
f(x)+g(x)+h(x)
#[1] 0.9760703 0.1873004 0.1266966
funadd(funadd(f,g),h)(x)
#[1] 0.9760703 0.1873004 0.1266966
或者,您可以使用这个:
funadd2 <- function(...){
function(x) Reduce(`+`, lapply(list(...), function(f) f(x)))
}
funadd2(f,g,h)(x)
#[1] 0.9760703 0.1873004 0.1266966
编辑:这是怎么回事:
查看 的源代码Reduce
,我们可以看到它(大致)有一个循环来执行此操作:
init <- f
init <- funadd(init, g)
如果有更多元素(init <- funadd(init, h)
,...),则继续。
这会导致引用f
在第一次循环迭代中丢失:
init(x)
# Error: evaluation nested too deeply: infinite recursion / options(expressions=)?
发生这种情况是因为f1
最后一个retfun
指向自身:
identical(environment(init)$f1, init, ignore.environment=FALSE)
# [1] TRUE
正如@Vincent 发现的那样,这也可以通过强制参数来解决,即通过制作一个避免对f1
and进行惰性求值的本地副本f2
:
funadd3 <- function(f1,f2){
f1.save <- f1
f2.save <- f2
retfun <- function(x){
f1.save(x)+f2.save(x)
}
retfun
}
Reduce(funadd3, list(f,g,h))(x)
# [1] 0.9760703 0.1873004 0.1266966