Hi, I have a problem that I'm finding a bit tricky. I'm trying to use mapply and assign to generate curried functions. For example, if I have the function divide divide <- function(x, y) { x / y } And I want the end result to be functionally equivalent to: half <- function(x) divide(x, 2) third <- function(x) divide(x, 3) quarter <- function(x) divide(x, 4) But I want to do it using mapply and assign: mapply(assign, c("half", "third", "quarter"), lapply(2:4, function(i) {function(x) divide(x, i)}), pos = 1) The problem is in the third line. I end up with 3 functions that are all functionally equivalent to quarter(). Any suggestions on how to get this to work properly. Thanks. James
On 3/12/2012 10:47 AM, J Toll wrote:> Hi, > > I have a problem that I'm finding a bit tricky. I'm trying to use > mapply and assign to generate curried functions. For example, if I > have the function divide > > divide<- function(x, y) { > x / y > } > > And I want the end result to be functionally equivalent to: > half<- function(x) divide(x, 2) > third<- function(x) divide(x, 3) > quarter<- function(x) divide(x, 4) > > But I want to do it using mapply and assign: > mapply(assign, > c("half", "third", "quarter"), > lapply(2:4, function(i) {function(x) divide(x, i)}), > pos = 1)The problem is with lazy argument evaluation/promises. i will be the last value of i (in this case 4) for all instances. You can change that. mapply(assign, c("half", "third", "quarter"), lapply(2:4, function(i) {force(i); function(x) divide(x, i)}), pos = 1) Note the inclusion of the force function. This gives expected results. > half(12) [1] 6 > third(12) [1] 4 > quarter(12) [1] 3> The problem is in the third line. I end up with 3 functions that are > all functionally equivalent to quarter(). Any suggestions on how to > get this to work properly. > > Thanks. > > > James >-- Brian S. Diggs, PhD Senior Research Associate, Department of Surgery Oregon Health & Science University
I think that adding a force(i) to your inner function should fix things up. > z <- mapply(assign, + c("half", "third", "quarter"), + lapply(2:4, function(i) { + force(i) + function(x) divide(x, i)}), + pos = 1) > half(10) [1] 5 > third(10) [1] 3.333333 > quarter(10) [1] 2.5 Bill Dunlap Spotfire, TIBCO Software wdunlap tibco.com> -----Original Message----- > From: r-help-bounces at r-project.org [mailto:r-help-bounces at r-project.org] On Behalf > Of J Toll > Sent: Monday, March 12, 2012 10:47 AM > To: r-help > Subject: [R] mapply & assign to generate functions > > Hi, > > I have a problem that I'm finding a bit tricky. I'm trying to use > mapply and assign to generate curried functions. For example, if I > have the function divide > > divide <- function(x, y) { > x / y > } > > And I want the end result to be functionally equivalent to: > half <- function(x) divide(x, 2) > third <- function(x) divide(x, 3) > quarter <- function(x) divide(x, 4) > > But I want to do it using mapply and assign: > mapply(assign, > c("half", "third", "quarter"), > lapply(2:4, function(i) {function(x) divide(x, i)}), > pos = 1) > > The problem is in the third line. I end up with 3 functions that are > all functionally equivalent to quarter(). Any suggestions on how to > get this to work properly. > > Thanks. > > > James > > ______________________________________________ > R-help at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code.