优雅地在ruby中实现'map(+1)list'

时间:2012-05-25 19:12:41

标签: ruby

标题中的短代码在Haskell中,它执行类似

的操作
list.map {|x| x + 1}

在红宝石中。

虽然我知道这种方式,但我想知道的是,在Haskell中如何在Haskell中实现同样的东西还有更优雅的方式。

我非常喜欢ruby中的to_proc快捷方式,例如:

[1,2,3,4].map(&:to_s)
[1,2,3,4].inject(&:+)

但这只接受Proc和方法之间完全匹配的参数编号。

我正在尝试寻找一种方法,允许将一个或多个参数额外传递到Proc中,而不使用像第一次演示那样无用的临时块/变量。

我想这样做:

[1,2,3,4].map(&:+(1))

红宝石有这样的举止吗?

6 个答案:

答案 0 :(得分:7)

如果您只想添加一个,那么您可以使用succ method

>> [1,2,3,4].map(&:succ)
=> [2, 3, 4, 5]

如果你想添加两个,你可以使用lambda:

>> add_2 = ->(i) { i + 2 }
>> [1,2,3,4].map(&add_2)
=> [3, 4, 5, 6]

对于任意值,您可以使用构建lambdas的lambda:

>> add_n = ->(n) { ->(i) { i + n } }
>> [1,2,3,4].map(&add_n[3])
=> [4, 5, 6, 7]

您还可以使用lambda生成方法:

>> def add_n(n) ->(i) { i + n } end
>> [1,2,3,4].map(&add_n(3))
=> [4, 5, 6, 7]

答案 1 :(得分:5)

使用ampex gem,它允许您使用X的方法来构建任何proc一个变量。以下是其规范中的一个示例:

["a", "b", "c"].map(&X * 2).should == ["aa", "bb", "cc"]

答案 2 :(得分:3)

您无法使用默认map直接执行此操作。但是,实现支持此类功能的版本非常容易。例如,Ruby Facets包含这样一种方法:

require 'facets/enumerable'

[1, 2, 3, 4].map_send(:+, 10)
=> [11, 12, 13, 14]

实现如下:

def map_send(meth, *args, &block)
  map { |e| e.send(meth, *args, &block) }
end

答案 3 :(得分:2)

此特定案例中,您可以使用以下内容:

[1, 2, 3, 4].map(&1.method(:+))

但是,这只能起作用,因为+不是关联的。例如,它不适用于-

答案 4 :(得分:1)

Ruby没有内置支持此功能,但您可以创建自己的扩展程序或使用小宝石“ampex”。它使用扩展的'to_proc'功能定义全局变量X.

它为您提供了这样做的可能性:

[1,2,3].map(&X.+(1))

甚至是:

"alpha\nbeta\ngamma\n".lines.map(&X.strip.upcase) 

答案 5 :(得分:0)

如果您只想添加1,可以使用nextsucc

[1,2,3,4].map(&:next)
[1,2,3,4].map(&:succ)