试图理解这个代码加法器[[1]](5)

时间:2016-01-03 18:02:31

标签: r lapply

以下代码来自Hadley Wickham撰写的 Advanced R 一书。它是lapply函数中的函数,不确定它是否有资格作为函数,但除此之外。代码由两个函数add()组成,定义为:

 add <- function(x) {
    function(y) x+y
 }

然后他使用add()adders“对象”,它的行为就像一个函数,但我不理解逻辑。我说它的行为就像一个函数,因为你可以像这样adders[[1]](10)编写代码,所以看起来adders[[1]]是一个函数。无论如何,他将adders定义为:

adders <- lapply(1:10,add)

在我看来,adders[[1]](10)中的10是add()函数中的“y”值。 1:10中的部分通过lapply表示add()函数的x,但是我不确定我是否理解逻辑。

1 个答案:

答案 0 :(得分:4)

  

此外,加法器[[x]]的行为就像一个函数,我们没有定义   它作为一种功能,至少不是经典的功能方式   定义加法器&lt; - function(x){---}

大概是通过&#34;经典方式&#34;,你的意思是一个命名函数,并指的是add中的最后一行:

function(y) x + y

与上述功能一样,函数不必具有关联名称 - 这些名称称为匿名函数。例如,您可以尝试运行

(function(a, b) a + b)(1, 2)

它会被立即评估,返回3 - 即使你没有将它分配给一个名字。由于它没有被分配给任何东西,它在完成评估后就会消失。另请注意以下事项:

class((function(a, b) a + b))
#[1] "function"

这是推动这个家庭的另一个例子:

add <- function(x) {
  force(x)
  function(y) x + y
  ## ^^^^^^^^^^^
  ## functionally equivalent to:
  ##
  ## f <- function(y) x + y
  ## return(f)
}

add_explicit <- function(x) {
  force(x)
  f <- function(y) x + y
  return(f)
}

(add(5))
#function(y) x + y
#<environment: 0x64106b0>

(add_explicit(5))
#function(y) x + y
#<environment: 0x637fe58>

虽然可以创建一个命名函数,但在add_explicit中,因为您实际上并没有按名称调用它(至少在您的问题的上下文中),这样做没有意义。

  

[...]但仍然与&#34; y&#34;混淆,如何访问和填写?   因为当你写加法器时[1]。 5分配给y,但它   感觉它应该去&#34; x&#34;因为当你编码add()时x是   内部唯一的元素()。

让我们将David Arenburg关于检查功能环境的建议应用于add(...)add_explicit(...)

ls.str(envir = environment(add(42)))
#x :  num 42

ls.str(envir = environment(add_explicit(42)))
#f : function (y)  
#x :  num 42

关于adders[[1]](5) - 相当于add(1)(5),因为用于创建它的表达式是lapply(1:[whatever], add) - 你说你觉得5应该对应x参数而不是(嵌套的)y参数。但正如上面的检查所示,x实际上不再是一个函数参数 - 它的值是&#34;固定的&#34;无论在add(x)被召唤时它是什么 - 在我的情况下是42。由于add返回了匿名函数,x是所有相应的环境显示。另一方面,add_explicit将表达式分配给名称(在其关联的环境中),您可以看到f仅是的函数 y 。因此,当您致电add([whatever])(5)时, 就是5对应y正文中的add变量的原因。

另外,请勿过多地挂在adders对象上。它恰好是list恰好存储函数,即:

lapply(1:2, add)
#[[1]]
#function (y) 
#x + y
#<environment: 0x7425ce0>

#[[2]]
#function (y) 
#x + y
#<environment: 0x74259d0>

虽然似乎出现 x在这样检查时仍然是(变化的)参数,但其值已经修复(在第一种情况下为1 ,和2以及第二种情况)。这一部分真正重要的是 - function (y) - 表示由list创建的lapply包含接受单个参数(y)的函数。 x已经有效地摆脱了桌面的影响。就名单而言。