问题描述
考虑以下功能:
addAmount <- function(x, amount) {
stopifnot(length(x) == 1)
return(x + amount)
}
它可以用于向 x
中添加一些 amount
:
It can be used to add some amount
to x
:
> addAmount(x = 5, amount = 3)
[1] 8
> addAmount(x = 2, amount = 3)
[1] 5
但是, x
的长度必须为1:
However, x
must be of length 1:
> addAmount(x = 7:9, amount = 3)
Error: length(x) == 1 is not TRUE
我有意添加此限制是为了举例说明.
I added this restriction intentionally for exemplification.
使用 Vectorize
,可以为 x
输入向量:
Using Vectorize
, it is possible to pass in a vector for x
:
> Vectorize(addAmount)(x = 7:9, amount = 3)
[1] 10 11 12
到目前为止,很好.
但是,我想使用currying将 addAmount
函数转换为"add 3"函数:
However, I'd like to turn my addAmount
function into a "add 3" function, using currying:
add3 <- functional::Curry(addAmount, amount = 3)
如果 x
的长度为1,则按预期方式工作;如果 x
的长度为1:
This works as expected if x
is of length 1 and fails (as expected) if x
is not of length 1:
> add3(x = 5)
[1] 8
> add3(x = 7:9)
Error: length(x) == 1 is not TRUE
问题是: add3
无法向量化:
> Vectorize(add3)(x = 7:9)
Error: length(x) == 1 is not TRUE
以某种方式,curried函数与 Vectorize
不兼容",即它的行为就好像它根本没有被向量化.
Somehow, the curried function is not "compatible" with Vectorize
, i.e. it behaves as if it had not been vectorized at all.
问题:我该怎么办?如何将currying和矢量化结合起来?(而且:出了什么问题?)
Question: What can I do about this? How can currying and vectorization be combined? (And: What is going wrong?)
我找到了一种解决方法(受到 Hadley的 add的大力启发
函数)使用环境而不是 Curry
,但是我正在寻找一种更清洁的解决方案,该解决方案不需要这种笨拙的工厂"函数:
I found a workaround (heavily inspired by Hadley's add
function) using environments instead of Curry
, but I'm looking for a cleaner solution that doesn't require this kind of clumsy "factory" functions:
getAdder <- function(amount) {
force(amount)
addAmount <- function(x) {
stopifnot(length(x) == 1)
return(x + amount)
}
return(addAmount)
}
add3 <- getAdder(3)
Vectorize(add3)(x = 7:9)
[1] 10 11 12
使用R 3.4.1和 functional
软件包(0.6版)进行了测试.
Tested with R 3.4.1 and the functional
package (version 0.6).
推荐答案
您可以在进行currying之前进行矢量化:
You can vectorize before currying:
add3 <- functional::Curry(Vectorize(addAmount), amount = 3)
add3(1:10)
这篇关于如何将Curry()与Vectorize()结合?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!