如何结合 Curry() 和 Vectorize()?
How to combine Curry() with Vectorize()?
考虑以下函数:
addAmount <- function(x, amount) {
stopifnot(length(x) == 1)
return(x + amount)
}
可以用来加一些amount
到x
:
> addAmount(x = 5, amount = 3)
[1] 8
> addAmount(x = 2, amount = 3)
[1] 5
但是,x
的长度必须为 1:
> addAmount(x = 7:9, amount = 3)
Error: length(x) == 1 is not TRUE
为了举例说明,我特意添加了这个限制。
使用Vectorize
,可以为x
传递一个向量:
> Vectorize(addAmount)(x = 7:9, amount = 3)
[1] 10 11 12
到目前为止,还不错。
但是,我想使用柯里化将我的 addAmount
函数变成 "add 3" 函数:
add3 <- functional::Curry(addAmount, amount = 3)
如果 x
的长度为 1,这将按预期工作,如果 x
的长度不是 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 函数不是 "compatible" 和 Vectorize
,即它的行为就好像它根本没有被矢量化一样。
问题:我该怎么办?如何结合柯里化和矢量化? (还有:出了什么问题?)
我找到了一种使用环境而不是 Curry
的解决方法(深受 Hadley's add
function 的启发),但我正在寻找一种不需要这种笨拙的更简洁的解决方案 "factory" 函数:
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)进行测试。
您可以在柯里化之前矢量化:
add3 <- functional::Curry(Vectorize(addAmount), amount = 3)
add3(1:10)
[1] 4 5 6 7 8 9 10 11 12 13
考虑以下函数:
addAmount <- function(x, amount) {
stopifnot(length(x) == 1)
return(x + amount)
}
可以用来加一些amount
到x
:
> addAmount(x = 5, amount = 3)
[1] 8
> addAmount(x = 2, amount = 3)
[1] 5
但是,x
的长度必须为 1:
> addAmount(x = 7:9, amount = 3)
Error: length(x) == 1 is not TRUE
为了举例说明,我特意添加了这个限制。
使用Vectorize
,可以为x
传递一个向量:
> Vectorize(addAmount)(x = 7:9, amount = 3)
[1] 10 11 12
到目前为止,还不错。
但是,我想使用柯里化将我的 addAmount
函数变成 "add 3" 函数:
add3 <- functional::Curry(addAmount, amount = 3)
如果 x
的长度为 1,这将按预期工作,如果 x
的长度不是 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 函数不是 "compatible" 和 Vectorize
,即它的行为就好像它根本没有被矢量化一样。
问题:我该怎么办?如何结合柯里化和矢量化? (还有:出了什么问题?)
我找到了一种使用环境而不是 Curry
的解决方法(深受 Hadley's add
function 的启发),但我正在寻找一种不需要这种笨拙的更简洁的解决方案 "factory" 函数:
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)进行测试。
您可以在柯里化之前矢量化:
add3 <- functional::Curry(Vectorize(addAmount), amount = 3)
add3(1:10)
[1] 4 5 6 7 8 9 10 11 12 13