I'm attempting to use a series of lapply
calls to build a list of curried functions, which ideally at the last lapply
call, returns the final desired value. The currying works, but lapply
seems to always applies the last element in the list after the second application.
Example:
curry <- function(fn, ...) {
arglist <- list(...)
function(...) {
do.call(fn, append(arglist, list(...)))
}
}
# rcurry is used only to init the first lapply.
rcurry <- function(v1, fn, ...) {
arglist <- append(list(v1), list(...))
function(...) {
do.call(fn, append(arglist, list(...)))
}
}
myadd <- function(a,b,c) {
a+b+c
}
This works as expected:
# you can achieve the same by closure:
# curry.a <- lapply(c(10, 1000), FUN = function(a) { curry(myadd, a) })
curry.a <- lapply(list(10, 1000), rcurry, myadd)
curry.a[[1]](1,2)
curry.a[[2]](1,2)
# > [1] 13
# > [1] 1003
The next lapply
of curry
"mangles the scope":
# this does give the desired output:
# curry.a.b <- list(curry(curry.a[[1]], 1), curry(curry.a[[2]], 1))
curry.a.b <- lapply(curry.a, curry, 1)
curry.a.b[[1]](2)
curry.a.b[[2]](2)
# > [1] 1003
# > [1] 1003
It doesn't seem like a result of the curry
or rcurry
function. Using roxygen
's Curry
function does the same thing. creating curry.a
by closure above or using curry.a <- list(curry(myadd, 10), curry(myadd, 1000))
also results the same.
And of course the final curry:
# it doesn't work if you re-define this:
# curry.a.b <- list(curry(curry.a[[1]], 1), curry(curry.a[[2]], 2))
curry.a.b.c <- lapply(curry.a.b, curry, 2)
lapply(curry.a.b.c, do.call, list())
# > [1] 1003
# > [1] 1003
What's going on here?