2009-09-08 20 views
7

Say Ho la seguente funzione:La valutazione pigra di argomenti forniti

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

Quando corro foo(1), il valore restituito è 2, come previsto. Tuttavia, non è possibile eseguire foo(1, y = max(m)) e ricevere 11, poiché la valutazione lazy funziona solo per gli argomenti predefiniti. Come posso fornire un argomento ma farlo valutare pigramente?

+0

"valutazione lazy funziona solo per argomenti predefiniti", ne sei sicuro? La valutazione lazy IIUC avviene con tutti gli argomenti della funzione. Il motivo per cui il tuo esempio non funziona è perché m non è nel campo di applicazione del chiamante. –

risposta

6

La semplice risposta è che non si può e non dovrebbe cercare di. Questo rompe la portata e potrebbe causare il caos se fosse permesso. Ci sono alcune opzioni che puoi pensare al problema in modo diverso.

primo passaggio y come funzione

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

se una semplice funzione non funziona è possibile spostare m una discussione con un valore predefinito.

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

Poiché questo è un esempio giocattolo Supporrei che sarebbe troppo banale. Se insisti a interrompere l'ambito, puoi passarlo come espressione che viene valutata esplicitamente.

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

Quindi è possibile restituire una funzione da un'altra funzione. E potrebbe funzionare anche per te, a seconda del tuo scopo.

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 

Ma ora stiamo iniziando a entrare nel ridicolo.

1

La mia soluzione era quella di cambiare solo l'argomento di default:

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

È possibile utilizzare una combinazione substitute, eval.

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 
Problemi correlati