2009-09-08 29 views
7

Nói rằng tôi có các chức năng sau:đánh giá Lazy của đối số cung cấp

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

Khi tôi chạy foo(1), giá trị trả về là 2, như mong đợi. Tuy nhiên, tôi không thể chạy foo(1, y = max(m)) và nhận được 11 vì việc đánh giá lười biếng chỉ hoạt động đối với các đối số mặc định. Làm thế nào tôi có thể cung cấp một đối số nhưng có nó đánh giá lười biếng?

+0

"đánh giá lười chỉ hoạt động cho đối số mặc định", bạn có chắc chắn về điều đó không? IIUC lười biếng đánh giá xảy ra với tất cả các đối số chức năng. Lý do ví dụ của bạn không hoạt động là vì m không nằm trong phạm vi của người gọi. –

Trả lời

6

Câu trả lời đơn giản là bạn không thể và không nên cố gắng. Điều đó phá vỡ phạm vi và có thể tàn phá nếu nó được cho phép. Có một vài tùy chọn mà bạn có thể suy nghĩ về vấn đề khác nhau.

đầu tiên vượt qua y như một hàm

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

nếu một chức năng đơn giản không hoạt động, bạn có thể di chuyển m đến một cuộc tranh cãi với một mặc định.

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

Vì đây là ví dụ về đồ chơi, tôi cho rằng điều này quá tầm thường. Nếu bạn nhấn mạnh vào phạm vi vi phạm sau đó bạn có thể vượt qua nó như là một biểu thức được đánh giá một cách rõ ràng.

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

Sau đó, có tùy chọn trả về một hàm từ một hàm khác. Và điều đó có thể phù hợp với bạn, tùy thuộc vào mục đích của bạn.

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 

Nhưng bây giờ chúng tôi đang bắt đầu nhận được vào vô lý.

1

giải pháp của tôi là chỉ cần thay đổi đối số mặc định:

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

Bạn có thể sử dụng kết hợp 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 
Các vấn đề liên quan