【问题标题】:R Curry weirdnessR咖喱怪异
【发布时间】:2015-08-08 22:40:27
【问题描述】:

我看到 library(roxygen) 中的 Curry 函数出现了奇怪的行为。这是一个最小的例子:

library(roxygen)
library(foreach)

f <- function(x,y,z) { return(x+y+z) }

fns <- list()
foreach(i=c(1:10))  %do% {
  f[[i]] <- Curry(Curry(f,i),i)
}

在这种情况下调用

f[[1]](0) 

返回 11。我期望 2。

有 2 个修复对我来说没有任何意义 - 一个是扁平化循环,如

fns <- list()
fns[[1]] <- Curry(Curry(f,1),1)
fns[[2]] <- Curry(Curry(f,2),2)
...

这行得通。此外,将单个函数评估放在原始循环中是可行的 - 就像

fns <- list()
foreach(i=c(1:10)) %do% {
  f[[i]] <- Curry(Curry(f,i),i)
  f[[i]](27)
}

然后我们有

f[[1]](0) = 2.

发生了什么事?

【问题讨论】:

    标签: r currying roxygen2 roxygen


    【解决方案1】:

    重述没有依赖关系的问题

    我假设Currydefined

    Curry<-function(FUN,...) {
      dots<-list(...);
      function(...) do.call(FUN,c(dots,list(...)))}
    

    然后

    f <- function(x,y,z) list(x,y,z)
    fns<-vector("list",10)
    for(i in 1:10) {fns[[i]]<-Curry(Curry(c,i),i)}
    fns[[1]](0)
    

    产量

    [1] 10  1  0
    

    表明 f 的第一个参数直到循环完成后才被评估。

    分析

    这是由于懒惰的评估。

    这里的罪魁祸首比Explain a lazy evaluation quirk 更微妙,这就是为什么我在标记为重复时胡扯。

    这里耽误的是FUN的评价

    CurryF<-function(FUN,...) {
      force(FUN); #needed for nesting Curry
      dots<-list(...);
      function(...) do.call(FUN,c(dots,list(...)))}
    

    现在再试一次

    for(i in 1:10) {fns[[i]]<-CurryF(CurryF(c,i),i)}
    fns[[1]](0)
    

    为了预期的结果

    [1] 1 1 0
    

    【讨论】:

    • 我认为这涵盖了它。所以懒惰的评估怪癖不是罪魁祸首 - 特别是,我会看到我在 2.8 和 3.2 中解释的行为(我目前无法检查)?
    • 更正 - 它是惰性评估/绑定。所以我不应该在 3.2 中看到这种行为。
    猜你喜欢
    • 1970-01-01
    • 2018-02-02
    • 1970-01-01
    • 2018-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多