Haskell Language
Composición de funciones
Buscar..
Observaciones
El operador de composición de función (.)
Se define como
(.) :: (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) ) )
El tipo (b -> c) -> (a -> b) -> (a -> c)
se puede escribir como (b -> c) -> (a -> b) -> a -> c
porque ->
en las firmas de tipo "asocia" a la derecha, correspondiente a la aplicación de función que asocia a la izquierda,
f g x y z ... == (((f g) x) y) z ...
Así que el "flujo de datos" es de derecha a izquierda: x
"va" a g
, cuyo resultado va a f
, produciendo el resultado final:
(.) 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
....
Sintácticamente, los siguientes son todos iguales:
(.) f g x = (f . g) x = (f .) g x = (. g) f x
que es fácil de entender como las "tres reglas de las secciones del operador ", donde el "argumento faltante" solo entra en la ranura vacía cerca del operador:
(.) f g = (f . g) = (f .) g = (. g) f
-- 1 2 3
La x
, al estar presente en ambos lados de la ecuación, puede omitirse. Esto se conoce como eta-contracción. Por lo tanto, la forma sencilla de anotar la definición para la composición de la función es simplemente
(f . g) x = f (g x)
Esto, por supuesto, se refiere al "argumento" x
; cada vez que escribimos (f . g)
sin la x
se conoce como estilo sin puntos.
Composición de derecha a izquierda
(.)
nos permite componer dos funciones, alimentando la salida de una como una entrada a la otra:
(f . g) x = f (g x)
Por ejemplo, si queremos cuadrar el sucesor de un número de entrada, podemos escribir
((^2) . succ) 1 -- 4
También hay (<<<)
que es un alias para (.)
. Asi que,
(+ 1) <<< sqrt $ 25 -- 6
Composición de izquierda a derecha
Control.Category
define (>>>)
, que, cuando se especializa en funciones, es
-- (>>>) :: 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)
Ejemplo:
sqrt >>> (+ 1) $ 25 -- 6.0
Composición con función binaria.
La composición regular trabaja para funciones únicas. En el caso de binario, podemos definir
(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
Así, (f .: g) = ((f .) . g)
por eta-contracción, y además,
(.:) f g = ((f .) . g)
= (.) (f .) g
= (.) ((.) f) g
= ((.) . (.)) f g
así que (.:) = ((.) . (.))
, una definición semi-famosa.
Ejemplos:
(map (+1) .: filter) even [1..5] -- [3,5]
(length .: filter) even [1..5] -- 2