为了理解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),就好像我刚刚定义了自己一样吗?
答案 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.new
或proc
,或使用“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))
如果你想这样调用它,你需要实际自己制作foo
和bar
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
然后你就可以实现你想做的事。