Ruby:返回另一个函数的函数

时间:2013-11-05 22:00:20

标签: ruby function

为了理解ruby的函数式编程部分,我想编写一个函数,它将2个函数f(x,y),g(x)作为参数并返回一个新函数h(x,y)= f( G(X),克(Y))。

def foo(x, y)
    return x+y
end

def bar(x)
    return 2*x
end

def comp(f,g)

end

f=comp(f,g)
f(1,2) #=> 6

我尝试过像

这样的事情
def comp(f,g)
    mylambda = lambda {|x,y| return f(g(x),g(y))}
    return mylambda
end
f=comp(foo, bar)
f.call(1,2)

我认为f现在是Proc,我可以称之为。但显然“在'foo'中:错误的参数数量(0表示2)(ArgumentError)”

我必须使用什么语法?并且有可能返回一个“真正的”函数而不是一个Proc,所以我可以只用f(1,2)来编写f(1,2),就好像我刚刚定义了自己一样吗?

5 个答案:

答案 0 :(得分:4)

这种类型的功能模式不像javascript或python那样顺畅地运行在更多功能语言上。由于ruby具有可选括号,因此编写foo与调用foo方法相同而不传递任何参数。

要获取对方法的引用,您需要使用Object#method方法:

def foo(x, y)
  x + y
end

def bar(x)
  x * 2
end

def comp(f, g)
  lambda { |x, y| f.call(g.call(x), g.call(y)) }
end

h = comp(method(:foo), method(:bar))
h.call(1, 2) # => 6

答案 1 :(得分:2)

试试这个:

def foo() lambda {|x,y| x+y} end
def bar() lambda {|x| 2*x} end
def comp(f,g) lambda {|x,y| f[g[x], g[y]]} end
h = comp(foo, bar)
h[1,2]       # => 6

或以下任何

h.call(1,2)  # => 6
h.(1,2)      # => 6
h.yield(1,2) # => 6

如果您愿意,

foo = lambda {|x,y| x+y}
bar = lambda {|x| 2*x}

在这个问题出现之前,我并没有意识到现在可以调用lambda(或proc)的无数方法。 (提供Proc#yield的理由让我感到惊讶,因为它与call相同,可能会与我们都知道和喜爱的无关的yield关键字混淆。)可以替代{{1} {}为Proc.newproc,或使用“stabby”语法lambda创建lambda(例如->

答案 2 :(得分:2)

Ruby没有像Python这样的第一类函数。 Ruby有lambda和方法对象,可以从方法中专门构造,但方法本身是不是对象。你最接近的是:

def foo(x, y)
    return x+y
end

def bar(x)
    return 2*x
end

def comp(f,g)
  return lambda {|x, y| f.call(g.call(x), g.call(y))}
end

f=comp(method(:f),method(:g))
f.call(1,2) #=> 6

此外,对于调用语法点,您可以使用方括号调用lambda,因此您可以这样做:

f[1,2]

答案 3 :(得分:2)

你所拥有的不是功能,它们是方法。函数(更确切地说:程序)定义如下:

foo = -> (x, y) { x + y }

bar = -> x { 2 * x }

comp = -> (f, g) { -> (x, y) { f.(g.(x), g.(y)) } }

f = comp.(foo, bar)

f.(1, 2) #=> 6

答案 4 :(得分:0)

f=comp(foo, bar)

这不会像在python中那样工作。您收到的错误消息是希望看到类似的内容。

f = comp(foo(1,2), bar(1))

如果你想这样调用它,你需要实际自己制作foobar lambdas(或返回lambdas的方法):

foo = lambda { |x, y| x + y }
bar = lambda { |x| 2 * x }

or

def foo(x, y)
  lambda { |x, y| x + y}
end

def bar(x)
  lambda { |x| 2 * x }
end

然后你就可以实现你想做的事。