【问题标题】:How to combine Curry() with Vectorize()?如何将 Curry() 与 Vectorize() 结合起来?
【发布时间】:2017-12-15 17:34:18
【问题描述】:

考虑以下函数:

addAmount <- function(x, amount) {
  stopifnot(length(x) == 1)
  return(x + amount)
}

可以用来给x添加一些amount

> 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 函数转换为“加 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 

不知何故,柯里化函数与Vectorize 不“兼容”,即它的行为就好像它根本没有被矢量化。

问题:对此我能做些什么?柯里化和向量化如何结合? (还有:出了什么问题?)


我找到了一种使用环境而不是Curry 的解决方法(很大程度上受到Hadley's add function 的启发),但我正在寻找一种不需要这种笨拙的“工厂”函数的更清洁的解决方案:

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 &lt;- functional::Curry(Vectorize(addAmount), amount = 3)
  • @eipi10 我正要写同样的评论 :) 详细说明 OP 的方法不起作用的原因:R 中的 currification 过程有点奇怪。 functional::Curry(addAmount, amount = 3) 返回一个只接受在自定义环境中处理的未命名参数 (...) 的函数。这不是Vectorize 函数可以使用的东西。另一方面,对Vectorize(addAmount) 返回的向量化函数进行柯里化是小菜一碟。
  • 备注:如果您真的想对 curried 函数进行矢量化,您可以使用 x 的命名包装器来实现:例如add3 = Vectorize(function(x){functional::Curry(addAmount, amount = 3)(x=x)}); add3(x=7:9)
  • 哦 - 我不知道为什么,但我从来没有想到在柯里化之前进行矢量化。我很乐意接受 eipi10 和 Jealie 的三个 cmets 的任何答案。谢谢你们!

标签: r functional-programming vectorization currying


【解决方案1】:

你可以在柯里化之前进行矢量化:

add3 <- functional::Curry(Vectorize(addAmount), amount = 3)

add3(1:10)

[1] 4 5 6 7 8 9 10 11 12 13

【讨论】:

    猜你喜欢
    • 2018-12-08
    • 2012-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-04
    • 2021-06-03
    • 2020-11-20
    相关资源
    最近更新 更多