gpt4 book ai didi

r - 为什么重复调用 lapply 后闭包中的变量值会丢失?

转载 作者:行者123 更新时间:2023-12-04 09:21:17 28 4
gpt4 key购买 nike

我正在尝试使用一系列 lapply调用来构建一个柯里化(Currying)函数列表,理想情况下在最后 lapply调用,返回最终的期望值。 currying 有效,但是 lapply似乎总是在第二次应用之后应用列表中的最后一个元素。

例子:

curry <- function(fn, ...) {
arglist <- list(...)
function(...) {
do.call(fn, append(arglist, list(...)))
}
}
# rcurry is used only to init the first lapply.
rcurry <- function(v1, fn, ...) {
arglist <- append(list(v1), list(...))
function(...) {
do.call(fn, append(arglist, list(...)))
}
}

myadd <- function(a,b,c) {
a+b+c
}

这按预期工作:
# you can achieve the same by closure:
# curry.a <- lapply(c(10, 1000), FUN = function(a) { curry(myadd, a) })
curry.a <- lapply(list(10, 1000), rcurry, myadd)
curry.a[[1]](1,2)
curry.a[[2]](1,2)

# > [1] 13
# > [1] 1003

下一个 lapplycurry “破坏范围”:
# this does give the desired output:
# curry.a.b <- list(curry(curry.a[[1]], 1), curry(curry.a[[2]], 1))
curry.a.b <- lapply(curry.a, curry, 1)
curry.a.b[[1]](2)
curry.a.b[[2]](2)

# > [1] 1003
# > [1] 1003

这似乎不是 curry 的结果或 rcurry功能。使用 roxygenCurry函数做同样的事情。创建 curry.a通过以上关闭或使用 curry.a <- list(curry(myadd, 10), curry(myadd, 1000))结果也一样。

当然还有最后的 curry :
# it doesn't work if you re-define this:
# curry.a.b <- list(curry(curry.a[[1]], 1), curry(curry.a[[2]], 2))
curry.a.b.c <- lapply(curry.a.b, curry, 2)
lapply(curry.a.b.c, do.call, list())

# > [1] 1003
# > [1] 1003

这里发生了什么?

最佳答案

fncurry不在函数范围内评估,因此它是 promise .
如果您 force然后你可以得到你所期望的:

curry <- function(fn, ...) {
force(fn)
arglist <- list(...)
function(...) {
do.call(fn, append(arglist, list(...)))
}
}

然后,
> curry.a.b <- lapply(curry.a, curry, 1)
> curry.a.b[[1]](2)
[1] 13
> curry.a.b[[2]](2)
[1] 1003
>
> curry.a.b.c <- lapply(curry.a.b, curry, 2)
> lapply(curry.a.b.c, do.call, list())
[[1]]
[1] 13

[[2]]
[1] 1003

更多内部信息, lapply生成一个局部变量 X每次调用函数都会引用它。如果 X调用 lapply 时不会在每个函数中进行评估, X是 promise 。调用 lapply后, X在来自 lapply 的所有函数调用中返回相同的(即最后一个)值。所以 lapply类似于:
f0 <- function(i) function() i
f1 <- function(i) {force(i); function() i}

f <- local({
r0 <- list()
r1 <- list()
for (i in 1:2) {
r0[[i]] <- f0(i)
r1[[i]] <- f1(i)
}
list(r0 = r0, r1 = r1)
})

然后,
> f$r0[[1]]()
[1] 2
> f$r1[[1]]()
[1] 1
> f$r0[[2]]()
[1] 2
> f$r1[[2]]()
[1] 2

关于r - 为什么重复调用 lapply 后闭包中的变量值会丢失?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10019477/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com