partial | R Documentation |
partial()
enables
partial application:
given a function, it fixes the value of selected arguments to produce a
function of the remaining arguments.
departial()
undoes the application of partial()
by returning the original
function.
partial(..f, ...) departial(..f)
..f |
Function. |
... |
Argument values of |
Even while partial()
truncates formals, it remains compatible with
functions that use missing()
to test whether a
specified argument was supplied in a call. For example,
draw3 <- partial(sample, size = 3)
works as a function that randomly
draws three elements, even though sample()
invokes missing(size)
and
draw3()
has the form function(x, replace, prob) {...}
.
Because partially applied functions call the original function in an ad hoc
environment, impure functions that depend on the calling context as a
value, rather than as a lexical scope, may not be amenable to
partial()
. For example, partial(ls, all.names = TRUE)()
is not
equivalent to ls(all.names = TRUE)
, because ls()
inspects the calling
environment to produce its value, whereas partial(ls, all.names = TRUE)()
calls ls(all.names = TRUE)
from an (ephemeral) evaluation environment.
partial()
returns a function whose formals are a
truncation of the formals of ..f
(as a closure) by the fixed arguments.
NB the original default values do not appear in the formals of a
partialized function, but are nonetheless applied when the function is
called.
The function partial(..f)
is identical to ..f
.
In conformance with R's calling convention, fixed argument values are lazy promises. Moreover, when forced, they are tidily evaluated. Lazy evaluation of fixed arguments can be overridden via unquoting, see ‘Examples’.
When ..f
is a partially applied function, departial(..f)
is the
(closure of) the underlying function. For ordinary (non-partially applied)
functions, departial(..f)
is identical to ..f
.
# Arguments can be fixed by name draw3 <- partial(sample, size = 3) draw3(letters) # Arguments can be fixed by position draw3 <- partial(sample, , 3) draw3(letters) # Use departial() to recover the original function stopifnot(identical(departial(draw3), sample)) # Lazily evaluate argument values by default # The value of 'n' is evaluated whenever rnd() is called. rnd <- partial(runif, n = rpois(1, 5)) replicate(4, rnd(), simplify = FALSE) # variable length # Eagerly evaluate argument values with unquoting (`!!`) # The value of 'n' is fixed when 'rnd_eager' is created. rnd_eager <- partial(runif, n = !!rpois(1, 5)) len <- length(rnd_eager()) reps <- replicate(4, rnd_eager(), simplify = FALSE) # constant length stopifnot(all(vapply(reps, length, integer(1)) == len)) # Mix evaluation schemes by combining lazy evaluation with unquoting (`!!`) # Here 'n' is lazily evaluated, while 'max' is eagerly evaluated. rnd_mixed <- partial(runif, n = rpois(1, 5), max = !!sample(10, 1)) replicate(4, rnd_mixed(), simplify = FALSE) # Arguments to fix can be spliced args_eager <- list(n = rpois(1, 5), max = sample(10, 1)) rnd_eager2 <- partial(runif, !!!args_eager) replicate(4, rnd_eager2(), simplify = FALSE) # Use rlang::exprs() to selectively evaluate arguments to fix args_mixed <- rlang::exprs(n = rpois(1, 5), max = !!sample(10, 1)) rnd_mixed2 <- partial(runif, !!!args_mixed) replicate(4, rnd_mixed2(), simplify = FALSE) # partial() truncates formals by the fixed arguments, omits default values foo <- function(x, y = x, ..., z = "z") NULL stopifnot( identical(formals(partial(foo)), formals(foo)), identical(formals(partial(foo, x = 1)), formals(function(y, ..., z) NULL)), identical(formals(partial(foo, x = 1, y = 2)), formals(function(..., z) NULL)), identical(formals(partial(foo, x = 1, y = 2, z = 3)), formals(function(...) NULL)) ) # Nevertheless, partial() remembers default argument values when called f <- function(x, y = x) c(x, y) p <- partial(f, x = 1) stopifnot(identical(p(), c(1, 1)))
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.