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