2016-02-02 14 views
8

Trong this introduction to functional programming, tác giả Hadley Wickham tạo nhà máy sau chức năng:Tạo một danh sách các chức năng sử dụng một vòng lặp trong R

power <- function(exponent) { 
    function(x) { 
    x^exponent 
} 
} 

Sau đó ông cho thấy cách chức năng này có thể được sử dụng để xác định các chức năng khác, chẳng hạn như

square <- power(2) 
cube <- power(3) 

Bây giờ giả sử tôi muốn tạo ra các chức năng đồng thời thông qua các vòng lặp sau:

ftns <- lapply(2:3, power) 

này dường như không làm việc, như 3 được gán cho số mũ cho tất cả các mục của danh sách:

as.list(environment(ftns[[1]])) 

$exponent 
[1] 3 

Ai đó có thể vui lòng giúp tôi hiểu những gì xảy ra với mã này?

Cảm ơn!

+2

Mã của bạn hoạt động như mong đợi đối với tôi: 'as.list (môi trường (ftns [[1]])) cho thấy số mũ là 2. –

+0

Tôi có thể hỏi bạn có sử dụng phiên bản cũ của R không? - Tôi có thể nhận được vấn đề của bạn trên một R 2.15 cũ tôi có trên một thanh bộ nhớ ở đây. – thelatemail

+0

@thelatemail Hmm thật kỳ quặc. Tôi đang sử dụng phiên bản R 3.1.3 (2015-03-09). – David

Trả lời

5

Những gì bạn thấy là hậu quả của việc sử dụng R của hứa hẹn để thực hiện đánh giá đối số lười biếng. Xem Promise objects.

Vấn đề là ở hàm power() đối số exponent không bao giờ được đánh giá, nghĩa là lời hứa cơ bản không bao giờ được gọi (ít nhất là cho đến khi hàm được tạo ra được đánh giá).

Bạn có thể buộc các lời hứa sẽ được đánh giá như thế này:

power <- function(exponent) { exponent; function(x) x^exponent; }; 
ftns <- lapply(2:3,power); 
sapply(ftns,function(ftn) environment(ftn)$exponent); 
## [1] 2 3 

Nếu không có sự exponent; tuyên bố để buộc đánh giá của lời hứa, chúng ta thấy vấn đề này:

power <- function(exponent) { function(x) x^exponent; }; 
ftns <- lapply(2:3,power); 
sapply(ftns,function(ftn) environment(ftn)$exponent); 
## [1] 3 3 

Aha! R changelog cho thấy rằng hành vi này đã được thay đổi trong 3.2.0:

* chức năng bậc cao như áp dụng các chức năng và giảm() nay buộc đối số cho các chức năng họ áp dụng để loại bỏ tương tác không mong muốn giữa đánh giá lười biếng và chụp biến trong bao đóng. Điều này giải quyết PR # 16093.

Được phân loại là tính năng mới.

+0

Bạn có chạy mã OP không? Không thể sao chép vấn đề. – Heroka

+0

@Heroka Tôi không chắc tại sao những người khác không thể tái tạo vấn đề. Có lẽ đó là một sự khác biệt phiên bản R? Tôi có 'R.version.string == 'R phiên bản 3.1.3 (2015-03-09)''. – bgoldst

Các vấn đề liên quan