代码之家  ›  专栏  ›  技术社区  ›  Charles Pehlivanian

R库里古怪

  •  1
  • Charles Pehlivanian  · 技术社区  · 9 年前

    我看到库(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。

    有两种修复方法对我来说毫无意义——一种是使循环变平,如

    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.
    

    发生什么事?

    1 回复  |  直到 9 年前
        1
  •  3
  •   Community kfsone    4 年前

    在没有依赖项的情况下重述问题

    我想 Curry defined

    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
    
    推荐文章