Bücher online kostenlos Kostenlos Online Lesen
Die Programmiersprache Ruby (German Edition)

Die Programmiersprache Ruby (German Edition)

Titel: Die Programmiersprache Ruby (German Edition) Kostenlos Bücher Online Lesen
Autoren: David Flanagan , Yukihiro Matsumoto
Vom Netzwerk:
für
Proc
als auch für
Method
funktionieren.
    Mit den oben definierten Methoden
apply
und
reduce
könnten wir unsere statistischen Berechnungen wie folgt umschreiben:
sum = lambda {|x,y| x+y } # Eine Funktion zur Addition zweier Zahlen
mean = (sum<=a)/a.size # Oder sum.reduce(a) oder a.inject(&sum)
deviation = lambda {|x| x-mean } # Funktion zur Berechnung der Differenz zu mean
square = lambda {|x| x*x } # Funktion zum Quadrieren einer Zahl
standardDeviation = Math.sqrt((sum<=square|(deviation|a))/(a.size-1))
    Beachten Sie, dass die letzte Zeile kurz und knapp ist, dass aber all die Nicht-Standard-Operatoren sie schlecht lesbar machen. Beachten Sie auch, dass der Operator
|
linksassoziativ ist, sogar wenn wir ihn selbst definieren. Die Syntax zur Anwendung mehrerer Funktionen auf ein
Enumerable
benötigt daher Klammern. Das heißt, wir müssen
square|(deviation|a)
statt
square|deviation|a
schreiben.
    6.8.2 Funktionen verknüpfen
    Wenn wir zwei Funktionen
f
und
g
haben, möchten wir manchmal eine neue Funktion
h
definieren, die
f(g())
oder f verknüpft mit g ist. Wir können eine Methode schreiben, die wie folgt automatisch Funktionsverknüpfungen durchführt:
module Functional
# Ein neues Lambda zurückgeben, das self[f[args]] berechnet
# * als Operator-Alias für compose verwenden
# Beispiele, die den Alias * für diese Methode verwenden
#
# f = lambda {|x| x*x }
# g = lambda {|x| x+1 }
# (f*g)[2] # => 9
# (g*f)[2] # => 5
#
# 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
# p,c = method :polar, method :cartesian
# (c*p)[3,4] # => [3,4]
#
def compose(f)
    if self.respond_to?(:arity) && self.arity == 1
     lambda {|*args| self[f[*args]] }
    else
     lambda {|*args| self[*f[*args]] }
    end
end
# * ist der natürliche Operator für eine Funktionsverknüpfung.
alias * compose
end
    Der Beispielcode im Kommentar demonstriert die Verwendung von
compose
sowohl mit
Method
-Objekten als auch mit Lambdas. Wir können diesen neuen
*
-Funktions-Kompositionsoperator verwenden, um unsere Berechnung der Standardabweichung leicht zu vereinfachen. Mithilfe derselben Definitionen der Lambdas
sum
,
square
und
deviation
sieht die Berechnung so aus:
standardDeviation = Math.sqrt((sum<=square*deviation|a)/(a.size-1))
    Der Unterschied besteht darin, dass wir
square
und
deviation
zu einer einzelnen Funktion verknüpfen, bevor wir sie auf das Array
a
anwenden.
    6.8.3 Funktionen partiell anwenden
    In der funktionalen Programmierung beschreibt partielle Anwendung den Vorgang, eine Funktion und eine Teilmenge von Argumentwerten zu nehmen und eine neue Funktion bereitzustellen, die äquivalent zu der ursprünglichen Funktion unter Festlegung der angegebenen Argumente ist, zum Beispiel
product = lambda {|x, y| x*y } # Eine Funktion mit zwei Argumenten
double = lambda {|x| product(2,x) } # Ein Argument anwenden
    Partielle Anwendung kann mithilfe entsprechender Methoden (und Operatoren) in unserem Modul
Functional
erleichtert werden:
module Functional
#
# Ein Äquivalent zum angegebenen Lambda zurückgeben,
# bei dem ein oder mehrere der ersten Argumente vom Anfang angewendet
# werden. Wenn nur ein einzelnes Argument angegeben wird,
# ist der Alias >> möglicherweise einfacher.
# Beispiel:
# product = lambda {|x,y| x*y}
# doubler = lambda >> 2
#
def apply_head(*first)
    lambda {|*rest| self[*first.concat(rest)]}
end
#
# Ein Äquivalent zum angegebenen Lambda zurückgeben,
# bei dem ein oder mehrere der letzten Argumente vom Anfang angewendet
# werden. Wenn nur ein einzelnes Argument angegeben wird,
# ist der Alias << möglicherweise einfacher.
# Beispiel:
# difference = lambda {|x,y| x-y }
# decrement = difference << 1
#
def apply_tail(*last)
    lambda {|*rest| self[*rest.concat(last)]}
end
# Hier sind Operator-Alternativen für diese Methoden. Die spitzen
# Klammern zeigen auf die Seite, auf der das Argument eingefügt wird.
alias >> apply_head # g = f >> 2 -- erstes Argument auf 2 setzen
alias << apply_tail # g = f << 2 -- letztes Argument auf 2 setzen
end
    Unter Verwendung dieser Methoden und Operatoren können wir unsere eigene
double
-Funktion einfach als
product>>2
definieren. Wir können die partielle Anwendung nutzen, um unsere Berechnung der Standardabweichung etwas abstrakter zu machen, indem wir unsere
deviation
-Funktion auf eine allgemeingültigere
difference
-Funktion aufbauen:
difference =

Weitere Kostenlose Bücher