2013-03-15 9 views
8

Niestety rzeczy jak (f+g)(3) gdzie f i g są zarówno unarne funkcje nie działają w R. Dlatego starałem się przeciążać operatora „+” dla funkcji jednoargumentowych w następujący sposób:Operator przeciążenie dla funkcji w R - dziwne zachowanie

"+.function" = function(e1, e2){ 
    return(function(x) e1(x) + e2(x)) 
} 

Ale jeśli spróbuję tego użyć, to nic nie da. Kod

powoduje taki sam błąd, ponieważ +.function nie jest nawet zdefiniowany.

Przez jakiś czas bawiąc się odkryłem, że istnieje możliwość dodania funkcji w ten sposób: jeśli funkcje są funkcjami składowymi klasy odniesienia, działa to! Tj. Następujący kod (wraz z definicją "+" z góry)

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

inst_a = clsA$new() 
(inst_a$b + inst_a$b)(2) 

zwraca "8" (zgodnie z oczekiwaniami). Dlatego mam już jakiś sposób obejścia mojego problemu. Teraz moje pytania to:

Jaki jest powód tego dziwnego zachowania? Dlaczego +.function nie dba o "zwykłą" funkcję, ale funkcje członka klasy? Czy ktoś ma pomysł, jak "rozwinąć" operatora do zwykłych funkcji?

+0

Jeśli ponownie zdefiniujesz klasę, na przykład jak klasa (a) <- "test", i ustaw "+ .funkcja" jako "+ .test", wtedy (a + a) (2) działa. Wygląda więc na to, że klasa funkcyjna jest w jakiś sposób wyjątkowa. –

+0

Fajnie, działa to :-) Cóż, można to uznać za obejście, ale uważam, że jest to dużo "mądrzejsze" obejście niż mój pomysł z klasą odniesienia. Bardzo dziękuję za ten pomysł! –

Odpowiedz

5

Jeśli redifine klasę a, na przykład jak class(a)<-"ownfunction" (lub jeszcze lepiej class(a)<-c("ownfunction","function"), i dokonać "+.function" jak "+.ownfunction" , następnie (a+a)(2) działa.

Wygląda na to, że klasa function jest traktowana w pewien szczególny sposób: jeśli uruchomisz debug("+.function");(a+a)(2), zobaczysz ten "+.function" nie jest nawet wywoływany.

EDYCJA: patrz komentarze.

+0

Na podstawie Twojego pomysłu: Jeśli zmienię definicję 'class (a) <-" function "' niż mój oryginalny operator '+ .function' działa dla' a', a także dla metod klasowych. Myślę, że byłoby to najmądrzejsze rozwiązanie. –

+0

@Patrick To prawda. Wierzę, że tak się dzieje, ponieważ po 'class (a) <-" function "', 'a' ma atrybut class' "function" ', co nie ma miejsca w przypadku normalnej funkcji. Jednak w obu przypadkach 'class (a)' zwraca '" funkcję "'. – QkuCeHBH

+0

Miło, więc mimo że funkcja 'class' nadaje' function' funkcję klasy funkcji, to tak naprawdę nie jest członkiem klasy 'function' :) –

3

Jako obejście, można zdefiniować special operator (%...%) tak:

"%+%" <- function(e1, e2) { 
    return(function(x) e1(x) + e2(x)) 
} 

a <- function(x) 2*x 
(a %+% a)(2) # == 8 
+0

Powoduje to dla mnie ten sam błąd, co podejście "+ .function". –

+0

Przepraszamy, zapomniałem zastąpić '+' z '% +%' ... teraz powinno działać – QkuCeHBH

+0

Dzięki, to wydawało się trochę dziwne, chociaż źle zrozumiałem znaczenie% +% .. –