Haskell Language
Composizione funzionale
Ricerca…
Osservazioni
L'operatore di composizione della funzione (.)
È definito come
(.) :: (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) ) )
Il tipo (b -> c) -> (a -> b) -> (a -> c)
può essere scritto come (b -> c) -> (a -> b) -> a -> c
perché il ->
in tipo firme "associa" a destra, corrispondente all'applicazione funzione associata a sinistra,
f g x y z ... == (((f g) x) y) z ...
Quindi il "flusso di dati" è da destra a sinistra: x
"passa" in g
, il cui risultato entra in f
, producendo il risultato finale:
(.) 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
....
Sintatticamente, le seguenti sono tutte uguali:
(.) f g x = (f . g) x = (f .) g x = (. g) f x
che è facile da cogliere come le "tre regole delle sezioni dell'operatore ", dove l'argomento "mancante" va semplicemente nello slot vuoto vicino all'operatore:
(.) f g = (f . g) = (f .) g = (. g) f
-- 1 2 3
La x
, presente su entrambi i lati dell'equazione, può essere omessa. Questo è noto come eta-contrazione. Quindi, il modo semplice per scrivere la definizione per la composizione della funzione è giusto
(f . g) x = f (g x)
Questo ovviamente si riferisce all '"argomento" x
; ogni volta che scriviamo solo (f . g)
senza x
è noto come stile senza punti.
Composizione da destra a sinistra
(.)
ci consente di comporre due funzioni, alimentando l'output di uno come input per l'altro:
(f . g) x = f (g x)
Ad esempio, se vogliamo quadrare il successore di un numero di input, possiamo scrivere
((^2) . succ) 1 -- 4
C'è anche (<<<)
che è un alias in (.)
. Così,
(+ 1) <<< sqrt $ 25 -- 6
Composizione da sinistra a destra
Control.Category
definisce (>>>)
, che, quando è specializzato in funzioni, lo è
-- (>>>) :: 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)
Esempio:
sqrt >>> (+ 1) $ 25 -- 6.0
Composizione con funzione binaria
La composizione regolare funziona per funzioni unarie. Nel caso del binario, possiamo definire
(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
Quindi, (f .: g) = ((f .) . g)
per eta-contrazione, e inoltre,
(.:) f g = ((f .) . g)
= (.) (f .) g
= (.) ((.) f) g
= ((.) . (.)) f g
quindi (.:) = ((.) . (.))
, una definizione semi-famosa.
Esempi:
(map (+1) .: filter) even [1..5] -- [3,5]
(length .: filter) even [1..5] -- 2