Operador punto en Haskell
Estoy tratando de entender qué está haciendo el operador de puntos en este código de Haskell:
sumEuler = sum . (map euler) . mkList
Respuesta corta
Código equivalente sin puntos, eso es solo
sumEuler = \x -> sum ((map euler) (mkList x))
o sin la lambda
sumEuler x = sum ((map euler) (mkList x))
porque el punto (.) indica la composición de la función.
Respuesta más larga
Primero, simplifiquemos la aplicación parcial de euler
a map
:
map_euler = map euler
sumEuler = sum . map_euler . mkList
Ahora solo tenemos los puntos. ¿Qué indican estos puntos?
De la fuente :
(.) :: (b -> c) -> (a -> b) -> a -> c
(.) f g = \x -> f (g x)
Así (.)
es el operador de composición .
Componer
En matemáticas, podríamos escribir la composición de funciones, f (x) y g (x), es decir, f (g (x)), como
(f ∘ g) (x)
que puede leerse "f compuesta con g".
Entonces en Haskell, f ∘ g, o f compuesta con g, se puede escribir:
f . g
La composición es asociativa, lo que significa que f (g (h (x))), escrito con el operador de composición, puede omitir los paréntesis sin ambigüedad.
Es decir, dado que (f ∘ g) ∘ h es equivalente af ∘ (g ∘ h), simplemente podemos escribir f ∘ g ∘ h.
Dando vueltas hacia atrás
Volviendo a nuestra simplificación anterior, esto:
sumEuler = sum . map_euler . mkList
solo significa que sumEuler
es una composición no aplicada de esas funciones:
sumEuler = \x -> sum (map_euler (mkList x))