r - R 保留列表循环中最后一个变量的奇怪行为?

标签 r functional-programming lazy-evaluation

当我创建一个循环来包装列表中的函数时,输入列表中的最后一个函数始终用于所有包装调用。

wrapper <- function(f)function()f()
fs <- list(f = function()"call f", g = function()"call g")
ws <- list()
for(n in names(fs))
    ws[[n]] <- wrapper(fs[[n]])
ws$f()
[1] "call g"

我期望在上面的代码中出现“call f”,但实际上它返回了“call g”

谁能解释一下为什么会发生这种情况?

标志是什么,或者在什么情况下我必须强制评估以避免类似

非常感谢

最佳答案

我终于找到了自己的答案

发生这种情况有两个原因:for循环没有自己的环境并且 wrapper确实延迟评估其参数 f .

第一个原因:for循环使用全局环境

对于后一个原因:更改 wrapperfunction(f){force(f); function()f()}导致了我在问题中的预期结果。

详细说明:

问题中的循环被解释为

for(n in names(fs)){
  tmp <- fs[[n]]
  ws[[n]] <- wrapper(tmp)
}

因为wrapper是否延迟评估参数 f ,它保持 f在其执行环境中但不保留其值。相反,它会记住如何评估 f当需要时。换句话说,它记住了 (<environment: R_GlobalEnv>, "tmp") 。 .

查看以下代码可以清除我所说的一切。

tmp <- f
wf <- wrapper(tmp)
tmp <- g
wf()
[1] "call g"

但是

tmp <- f
wf <- wrapper(tmp)
wf()
[1] "call f"
tmp <- g
wf()
[1] "call f"

后一个代码打印 "call f"在第二次通话中,因为 f被评估并存储在wrapper中的环境,无需再次评估(成为 g )

关于r - R 保留列表循环中最后一个变量的奇怪行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47949635/

相关文章:

java - 在 Java8 中引入 lambda 会改变或影响哪种 GoF 设计模式?

haskell - 为什么尾递归模数可以优化?

c++ - C++ 中的延迟转换

haskell - Eager 与 Lazy Haskell。 Eager 语言中可能有无限列表吗?

r - 在 R 中使用 googlesheets 覆盖工作表

haskell - 什么构成了列表以外类型的折叠?

R Shiny 读取 csv 文件

lazy-evaluation - 精益 4 是懒惰的还是严格的?

r - 在 SparkR 中的 DataFrame 列上使用 substr()

r - R控制台中的上一个命令