运算符重载R中的函数 - 奇怪的行为

Pat*_*cks 8 oop r class function reference-class

不幸的是,像(f+g)(3)f和g这两个都是一元函数的东西在R中不起作用.因此,我尝试以下列方式重载"+"运算符以获得一元函数:

"+.function" = function(e1, e2){
  return(function(x) e1(x) + e2(x))
}
Run Code Online (Sandbox Code Playgroud)

但如果我尝试使用它,这什么都不做.代码

 a = function(x) 2*x
 (a+a)(2)
Run Code Online (Sandbox Code Playgroud)

产生相同的错误,如果+.function没有定义.

通过一段时间的游戏,我发现事实上有可能以这种方式添加函数:如果函数是引用类的成员函数,这是有效的!即,以下代码(连同上面的"+"定义)

clsA = setRefClass("clsA", 
  methods = list(
    b = function(x) 2*x
  ))

inst_a = clsA$new()
(inst_a$b + inst_a$b)(2)
Run Code Online (Sandbox Code Playgroud)

返回"8"(如预期的那样).因此,我已经为我的问题找到了某种解决方法.现在我的问题是:

这种奇怪行为的原因是什么?为什么不+.function关心"通常"功能而是关注类成员函数?有谁知道如何将操作员"扩展"到通常的功能?

Jou*_*ske 5

如果您redifine类的a,例如像class(a)<-"ownfunction"(或更好class(a)<-c("ownfunction","function"),并让你的"+.function"作为"+.ownfunction",那么(a+a)(2)工作.

似乎以function一种特殊的方式对待这个类:如果你运行,debug("+.function");(a+a)(2)你会看到"+.function"甚至没有被调用.

编辑:见评论.

  • 关于这个解决方案的另一个评论:要允许像(f + g + h)(2)这样的表达式,应该使用`{res = function(x)e1(x)+ e2(x); class(res)="function"; return(res)}`另外:使用`...`而不是`x`也允许n-ary函数,即(u + v)(2,2).并且将`+`替换为`Ops`和`.Primitive(.Generic)`分别概括了解决方案. (3认同)
  • 发生这种情况的原因是`is.object(function(){})`是`FALSE`因此不会发生内部S3调度.这是一种性能优化,可以避免在使用基本类型时方法调度的开销. (2认同)
  • @JoshO'Brien没有OBJECT位集的基本类型.您必须添加类属性,或使用S4对象. (2认同)