2009-09-08 18 views
7

że mam następującą funkcję:Lazy oceny dostarczonych argumentów

foo <- function(x, y = min(m)) { 
    m <- 1:10 
    x + y 
} 

Kiedy biegnę foo(1), zwracana wartość jest 2, jak oczekiwano. Jednak nie można uruchomić foo(1, y = max(m)) i otrzymać 11, ponieważ leniwy oceny działa tylko dla domyślnych argumentów. Jak mogę podać argument, ale czy leniwie go oceniam?

+0

"Leniwe oceny działa tylko dla domyślnych argumentów", czy jesteś tego pewien? Ocena leniwy IIUC odbywa się przy wszystkich argumentach funkcji. Powód, dla którego twój przykład nie działa, polega na tym, że m nie znajduje się w zasięgu dzwoniącego. –

Odpowiedz

6

Prosta odpowiedź jest taka, że ​​nie można i nie powinno próbować. To łamie zakres i może siać spustoszenie, jeśli jest to dozwolone. Jest kilka opcji, które możesz inaczej pomyśleć o problemie.

pierwszy przebieg y jako funkcję

foo<-function(x,y=min){ 
m<-1:10 
x+y(m) 
} 

jeśli prosta funkcja nie działa, można przenieść m do argumentu z domyślnie.

foo<-function(x,y=min(m),m=1:10){ 
x+y(m) 
} 

Ponieważ jest to przykład zabawkowy, zakładam, że byłoby to zbyt trywialne. Jeśli nalegasz na łamanie zakresu, możesz przekazać go jako wyrażenie, które jest jednoznacznie ocenione.

foo<-function(x,y=expression(min(m))){ 
m<-1:10 
x+eval(y) 
} 

Następnie istnieje możliwość zwrócenia funkcji z innej funkcji. I to może zadziałać również dla ciebie, w zależności od twojego celu.

bar<-function(f)function(x,y=f(m)){ 
m<-1:10 
x+y 
} 
foo.min<-bar(min) 
foo.min(1) #2 
foo.max<-bar(max) 
foo.max(1) #10 

Ale teraz zaczynamy wpadać w niedorzeczność.

1

Moje rozwiązanie było tylko zmienić domyślny argument:

R> formals(foo)$y <- call("max", as.name("m")) 
R> foo(1) 
[1] 11 
0

Można używać kombinacji substitute, .

foo <- function(x, y = min(m)) { 
    y <- substitute(y) 
    m <- 1:10 
    x + eval(y) 
} 

foo(1) 
## [1] 2 
foo(1, y = max(m)) 
## [1] 11 
Powiązane problemy