In order to understand the functional programming part of ruby I want to write a function that takes 2 functions f(x,y),g(x) as arguments and returns a new function h(x,y)=f(g(x),g(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
I tried things like
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)
I thought f would be a Proc now, and I could just call it. But apparently "in `foo': wrong number of arguments (0 for 2) (ArgumentError)"
What syntax would I have to use? And is it possible to return a "real" function instead of a Proc, so that instead of f.call(1,2) I could just writhe f(1,2) like if I had just defined f myself normaly?
This type of functional pattern doesn't work as smoothly as on more functional languages, as javascript or python. Since ruby has optional parentheses, writing foo
is the same as calling the foo
method without passing any arguments.
To get a reference to a method, you need to use the Object#method
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
Ruby doesn't have first class functions like Python. Ruby has lambdas, and method objects that can be constructed specially from a method, but methods themselves are not objects. The closest you'll get to this is this:
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
Also, for the calling syntax point, you can call a lambda with square brackets, so you could do this:
f[1,2]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With