r - R 中的函数工厂

标签 r functional-programming

我试图通过返回一个专门函数的字典来提出一个函数工厂,或多或少像函数式编程风格。我尝试在以下代码中执行此操作。

require(hash)

names = c("aa","bb","cc");
funs = hash()
for (i in seq(length(names))) {
  n = names[i]
  funs[[n]] = function(x) { 
    print(paste(n,":",x, sep="")) 
 }
}

显然,我在数组中有 3 个函数;但是,它们的行为都与迭代中的最后一个函数相同。
> funs[["aa"]](1)
[1] "cc:1"
> funs[["bb"]](2)
[1] "cc:2"
> funs[["cc"]](3)
[1] "cc:3"

我的猜测是 R 没有创建新的函数实例,而是在 for 循环内重用了相同的函数对象。

我尝试以下希望 R 将创建不同的函数对象,
  funs[[n]] = eval(parse(text="function(x) { print(paste(n,':',x, sep='')) }"))

但它的工作原理与第一个相同。

你知道如何创建一个生成不同函数对象的生成器吗?

最佳答案

根据哈德利的 Advanced R Programmin, Lexical scoping ,变量 n在函数体中 funs[['aa']] , funs[['bb']] , 和 funs[['cc']]是变量 n<environment: R_GlobalEnv> .

例如:

> funs[["aa"]](1)
[1] "cc:1"
> n <- "1234"
> funs[["aa"]]("1")
[1] "1234:1"

为了做你想做的事,我将编写一个返回一个函数的函数:
funs.gen <- function(n) {
  force(n)
  function(x) {
    print(paste(n, ":", x, sep=""))
  }  
}

names = c("aa","bb","cc");
funs = hash()
for (i in seq(length(names))) {
  n = names[i]
  funs[[n]] = funs.gen(n)
}

funs[["aa"]](1)
funs[["bb"]](2)
funs[["cc"]](3)

请注意 force用于询问 R 不惰性求值表达式 n .如果你删除它,那么 R 将评估 n出了for循环将产生与您的问题相同的结果。

关于r - R 中的函数工厂,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19749923/

相关文章:

r - dplyr - 获取要汇总的 group_by 数量

r - 如何使用 ggplot2 和刻度格式化带有指数的轴标签?

r - 在 R 中规范化数据

r - 嵌套列表中的唯一类

kotlin - 如何在 Kotlin 中构造函数式代码?

JavaScript 的 bind() 带有柯里化(Currying)。这些代码是如何工作的?

r - 在R中调整矩阵大小的函数

.net - F#中的Seq.map和Seq.collect之间的区别

java - 如何在 Java8 流中管理附带效果

java - 柯里化(Currying)一个现有的静态函数