名称对应于现有函数名称的函数自变量的默认值

时间:2019-01-11 14:40:09

标签: r functional-programming arguments parameter-passing

是否有一种方法可以防止

时发生promise already under evaluation错误
  1. 您希望函数参数的名称成为现有函数的名称
  2. 您要为此特定参数设置默认值
  3. 您是否希望仅使用其默认值即可调用外部函数(即,无需将显式值传递给每个参数)?

在下面的示例中,虽然foo(1:5, bar)有效,但是foo(1:5)会引发这样的错误。

当然,我可以将参数名称从bar更改为bar_fun,但如果可能的话,我宁愿使用实际函数的名称。

foo <- function(x, bar = bar) {
  bar(x)
}
bar <- function(x) {
  UseMethod("bar")
}
bar.default <- function(x) {
  sum(x)
}
foo(1:5)
#> Error in foo(1:5): promise already under evaluation: recursive default argument reference or earlier problems?
foo(1:5, bar)
#> [1] 15

动机(一阶)

实际使用情况是bar()实际上是settings(),该函数返回设置列表。我想对这些设置进行版本控制。所以会有例如settings.v1settings.v2,...和settings.default之类的方法。 而且我想到了使用settings.default来定义要使用的设置的“运行时版本”,例如:

settings <- function(x) {
  UseMethod("settings")
}

settings.v1 <- function(x) {
  list(system = "dev")
}

settings.v2 <- function(x) {
  list(system = "production")
}

settings.default <- function(x) {
  settings.v2(
}

foo <- function(x, settings = settings) {
  settings()
}

foo()
#> Error in foo(): promise already under evaluation: recursive default argument reference or earlier problems?
foo(settings = settings)
#> $system
#> [1] "production"

由于settings.default()调用了我要使用的设置方法,因此,如果我可以使用其默认值调用foo()(那将总是使用settings.default()方法,那就太好了) )。

动机(二阶)

我正在尝试更多地遵循函数式编程的原理(例如,参见chapter from Advanced Rwikipedia link)及其对 pure ffectful / side-有效的功能。

以前,我可能会通过某种 global 变量来实现设置,因此每个foo()都可以访问,因此我可能很懒,并且不将其定义为函数foo(),但是foo()则取决于其范围的外部-在FP中这是非常糟糕的事情。

现在,我想通过向其传递一个返回设置值的函数至少声明foo()对我设置的依赖关系-这有点儿我的懒惰,至少符合顶级FP原理的某些扩展

当然,非延迟(最好是最好的)解决方案是仔细地将所有实际设置的依赖关系逐一声明为foo()中的函数参数,例如foo(settings_system = settings()$system);-)

1 个答案:

答案 0 :(得分:3)

1)尝试明确地从父级获取它:

foo <- function(x, bar = get("bar", 1)) {
  bar(x)
}

2)另一种可能性是使用参数名称,例如bar.。用户仍然可以写foo(1:15, bar = whatever),例如这三个调用中的任何一个都起作用:

foo <- function(x, bar. = bar) {
  bar.(x)
}

foo(1:5)
foo(1:5, bar) 
foo(1:5, bar = bar)