Haskell Language
Functie samenstelling
Zoeken…
Opmerkingen
Functiecompositie-operator (.)
Is gedefinieerd 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) ) )
Het type (b -> c) -> (a -> b) -> (a -> c)
kan worden geschreven als (b -> c) -> (a -> b) -> a -> c
omdat de ->
in typeaanduidingen "associeert" aan de rechterkant, overeenkomend met de functie-applicatie die links associeert,
f g x y z ... == (((f g) x) y) z ...
Dus de "gegevensstroom" is van rechts naar links: x
"gaat" naar g
, waarvan het resultaat naar f
, wat het eindresultaat oplevert:
(.) 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
....
Syntactisch zijn de volgende allemaal hetzelfde:
(.) f g x = (f . g) x = (f .) g x = (. g) f x
die gemakkelijk te begrijpen is als de "drie regels van operatorsecties ", waarbij het "ontbrekende argument" gewoon in het lege vak bij de operator komt:
(.) f g = (f . g) = (f .) g = (. g) f
-- 1 2 3
De x
, aanwezig aan beide zijden van de vergelijking, kan worden weggelaten. Dit staat bekend als eta-contractie. De eenvoudige manier om de definitie voor functiesamenstelling op te schrijven is dus gewoon
(f . g) x = f (g x)
Dit verwijst natuurlijk naar het "argument" x
; wanneer we alleen (f . g)
zonder de x
, staat het bekend als puntloze stijl.
Samenstelling van rechts naar links
(.)
laat ons twee functies samenstellen, uitvoer van de ene als invoer voor de andere:
(f . g) x = f (g x)
Als we bijvoorbeeld de opvolger van een invoernummer willen kwadrateren, kunnen we schrijven
((^2) . succ) 1 -- 4
Er is ook (<<<)
wat een alias is voor (.)
. Zo,
(+ 1) <<< sqrt $ 25 -- 6
Van links naar rechts compositie
Control.Category
definieert (>>>)
, wat, wanneer het gespecialiseerd is in functies, is
-- (>>>) :: 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)
Voorbeeld:
sqrt >>> (+ 1) $ 25 -- 6.0
Samenstelling met binaire functie
De reguliere compositie werkt voor unaire functies. In het geval van binair kunnen we definiëren
(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
Dus (f .: g) = ((f .) . g)
door eta-contractie, en bovendien,
(.:) f g = ((f .) . g)
= (.) (f .) g
= (.) ((.) f) g
= ((.) . (.)) f g
so (.:) = ((.) . (.))
, een semi-beroemde definitie.
Voorbeelden:
(map (+1) .: filter) even [1..5] -- [3,5]
(length .: filter) even [1..5] -- 2