Ruby中的乱序


Ruby中,有没有办法按顺序来调整函数参数

他们最初被宣布?

这是一个非常简单的例子来证明我的意思:

# Example data, an array of arrays
list = [
  [11, 12, 13, 14],
  [21, 22, 23, 24],
  [31, 32, 33, 34],
  [41, 42, 43, 44]
]

# Declare a simple lambda
at = ->(arr, i) { arr[i] }

返回第一个数组的第一个元素,第二个元素
第二个数组等,你可以使用#with_index:

# Supply the lambda with each array, and then each index
p list.map.with_index(&at)

# => [11, 22, 33, 44]

但这个用例有点人为.这个& at更实际的用途
lambda将返回,例如,每个数组中的第二个元素.

看来我必须用交换的参数重新声明lambda,因为
我想要讨论的论点不在第一位:

# The same lambda, but with swapped argument positions
at = ->(i, arr) { arr[i] }

# Supply the lambda with the integer 1, and then each array
p list.map(&at.curry[1])

# => [12, 22, 32, 42]

或者通过创建如下所示的代理接口:

at_swap = ->(i, arr) { at.call(arr, i) }

它是否正确?有没有办法咖喱失序?我觉得这样
将有助于我们更好地重用过程和方法,但也许是有用的
我忽视了一些事情.

这个网站上有一些类似的问题,但都没有具体的答案或解决方法.

Ruby Reverse Currying: Is this possible?

Ruby rcurry. How I can implement proc “right” currying?

Currying a proc with keyword arguments

最佳答案 目前Ruby的标准库没有提供这样的选项.

但是,您可以轻松实现一个自定义方法,该方法允许您更改Procs和lambdas的参数顺序.例如,我将模仿Haskell的flip功能:

flip f takes its (first) two arguments in the reverse order of f

它在Ruby中会是什么样子?

def flip
  lambda do |function|
    ->(first, second, *tail) { function.call(second, first, *tail) }.curry
  end
end

现在我们可以使用这种方法来改变lambda的顺序.

concat = ->(x, y) { x + y }
concat.call("flip", "flop") # => "flipflop"

flipped_concat = flip.call(concat)
flipped_concat.call("flip", "flop") # => "flopflip"
点赞