En esta sección ampliamos el módulo Functional con el operador
* para denotar la composición de procs, lambdas y methods.
De esta forma, el anterior ejemplo puede reescribirse de este modo:
if __FILE__ == $0
def polar(x,y)
[Math.hypot(y,x), Math.atan2(y,x)]
end
def cartesian(magnitude, angle)
[magnitude*Math.cos(angle), magnitude*Math.sin(angle)]
end
f = lambda {|x| x*x }
g = lambda {|x| x+1 }
puts (f*g)[2] # => 9
puts (g*f)[2] # => 5
p,c = method(:polar), method(:cartesian)
puts (c*p)[3,4] # => [3,4]
a = (1..5).to_a
sum = lambda {|x,y| x+y } # A function to add two numbers
mean = (sum<=a)/a.size # Or sum.reduce(a) or a.inject(&sum)
deviation = lambda {|x| x-mean } # Function to compute difference from mean
square = lambda {|x| x*x } # Function to square a number
puts sum<=square*deviation|a # 10 = 4 + 1 + 4 + 1
standardDeviation = Math.sqrt((sum<=square*deviation|a)/(a.size-1).to_f)
puts standardDeviation # sqrt(10/4) = 1.5811388300841898
end
~/TheRubyProgrammingLanguage/Chapter6MethodsProcsLambdasAndClosures]$ cat functional_compose.rb
require './functional'
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