Haskell Language
Funktionszusammenstellung
Suche…
Bemerkungen
Der Funktionszusammensetzungsoperator (.)
Ist definiert als
(.) :: (b -> c) -> (a -> b) -> (a -> c)
(.) f g x = f (g x) -- or, equivalently,
(.) f g = \x -> f (g x)
(.) f = \g -> \x -> f (g x)
(.) = \f -> \g -> \x -> f (g x)
(.) = \f -> (\g -> (\x -> f (g x) ) )
Der Typ (b -> c) -> (a -> b) -> (a -> c)
kann als (b -> c) -> (a -> b) -> a -> c
da der ->
in Typensignaturen "Associates" nach rechts, entsprechend der Funktionsanwendung, die links zugeordnet ist,
f g x y z ... == (((f g) x) y) z ...
Der "Datenfluss" ist also von rechts nach links: x
"geht" in g
, dessen Ergebnis in f
geht und das Endergebnis erzeugt:
(.) f g x = r
where r = f (g x)
-- g :: a -> b
-- f :: b -> c
-- x :: a
-- r :: c
(.) f g = q
where q = \x -> f (g x)
-- g :: a -> b
-- f :: b -> c
-- q :: a -> c
....
Syntaktisch sind die folgenden alle gleich:
(.) f g x = (f . g) x = (f .) g x = (. g) f x
Dies ist leicht zu verstehen als die "drei Regeln für Operatorabschnitte ", bei denen das "fehlende Argument" nur in den leeren Platz in der Nähe des Operators geht:
(.) f g = (f . g) = (f .) g = (. g) f
-- 1 2 3
Das auf beiden Seiten der Gleichung vorhandene x
kann weggelassen werden. Dies wird als Eta-Kontraktion bezeichnet. Daher ist der einfache Weg, die Definition für die Funktionszusammenstellung aufzuschreiben, einfach
(f . g) x = f (g x)
Dies bezieht sich natürlich auf das "Argument" x
; wann immer wir nur (f . g)
ohne x
schreiben, wird es als punktfreier Stil bezeichnet.
Rechts-nach-Links-Komposition
(.)
können wir zwei Funktionen zusammenstellen, deren Ausgabe als eine Eingabe an die andere übergeben wird:
(f . g) x = f (g x)
Wenn wir zum Beispiel den Nachfolger einer Eingangsnummer quadrieren wollen, können wir schreiben
((^2) . succ) 1 -- 4
Es gibt auch (<<<)
einen Alias für (.)
. So,
(+ 1) <<< sqrt $ 25 -- 6
Links-nach-Rechts-Komposition
Control.Category
definiert (>>>)
, was auf Funktionen spezialisiert ist
-- (>>>) :: Category cat => cat a b -> cat b c -> cat a c
-- (>>>) :: (->) a b -> (->) b c -> (->) a c
-- (>>>) :: (a -> b) -> (b -> c) -> (a -> c)
( f >>> g ) x = g (f x)
Beispiel:
sqrt >>> (+ 1) $ 25 -- 6.0
Komposition mit binärer Funktion
Die reguläre Komposition arbeitet für unäre Funktionen. Im Falle von binär können wir definieren
(f .: g) x y = f (g x y) -- which is also
= f ((g x) y)
= (f . g x) y -- by definition of (.)
= (f .) (g x) y
= ((f .) . g) x y
Somit ist (f .: g) = ((f .) . g)
durch Eta-Kontraktion und weiterhin
(.:) f g = ((f .) . g)
= (.) (f .) g
= (.) ((.) f) g
= ((.) . (.)) f g
so (.:) = ((.) . (.))
, eine halbbekannte Definition.
Beispiele:
(map (+1) .: filter) even [1..5] -- [3,5]
(length .: filter) even [1..5] -- 2