compose(*)函数如何在Ruby中工作(来自Ruby编程语言)?

时间:2014-09-03 16:11:58

标签: ruby functional-programming

摘录Ruby编程语言:

module Functional
  def compose(f)
    if self.respond_to?(:arity) && self.arity == 1
      lambda {|*args| self[f[*args]] }
    else
      lambda {|*args| self[*f[*args]] }
    end
  end
  alias * compose
end

class Proc; include Functional; end
class Method; include Functional; end

f = lambda {|x| x * 2 }
g = lambda {|x, y| x * y}
(f*g)[2, 3] # => 12

if / else子句中f和* f有什么区别?

2 个答案:

答案 0 :(得分:5)

*或者将所有项目收集到一个数组中,或者将数组分解为单个元素 - 具体取决于上下文。

如果args = [1, 2, 3],则:

  • f[args]相当于f[ [1, 2, 3] ] #There is one argument: an array.
  • f[*args]相当于f[1, 2, 3] #There are three arguments.

如果f[*args]返回[4, 5, 6],则:

  • self[f[*args]]相当于self[ [4, 5, 6] ] #self is called with 1 arg.
  • self[*f[*args]]相当于self[4, 5, 6] #self is called with 3 args.

用于将项目收集到数组中的*的示例是:

  • lambda {|*args| ....}

您可以使用任意数量的参数调用该函数,并且所有参数将被收集到一个数组中并分配给参数变量args

答案 1 :(得分:0)

*(也称为splat)允许您使用参数数组调用方法,而不是单独传递值。如果你离开了splat,那么ruby只会传递一个值(恰好是一个数组)。此一元*不是此代码定义为*的别名的compose操作

在if分支self的arity为1时,f应返回单个值,因此不需要splat。

在else分支self中有多个参数,因此f应该返回一个值数组,而splat用于使用这些参数调用self。< / p>