如何将Curry()与Vectorize()结合? [英] How to combine Curry() with Vectorize()?

查看:62
本文介绍了如何将Curry()与Vectorize()结合?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑以下功能:

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)

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

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

这篇关于如何将Curry()与Vectorize()结合?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆