Operador de ponto em Haskell
Estou tentando entender o que o operador ponto está fazendo neste código Haskell:
sumEuler = sum . (map euler) . mkList
Resposta curta
Código equivalente sem pontos, isso é apenas
sumEuler = \x -> sum ((map euler) (mkList x))
ou sem o lambda
sumEuler x = sum ((map euler) (mkList x))
porque o ponto (.) indica a composição da função.
Resposta mais longa
Primeiro, vamos simplificar a aplicação parcial de euler
para map
:
map_euler = map euler
sumEuler = sum . map_euler . mkList
Agora temos apenas os pontos. O que é indicado por esses pontos?
Da fonte :
(.) :: (b -> c) -> (a -> b) -> a -> c
(.) f g = \x -> f (g x)
Assim (.)
é o operador de composição .
Compor
Em matemática, podemos escrever a composição das funções, f (x) e g (x), ou seja, f (g (x)), como
(f ∘ g) (x)
que pode ser lido como "f composto com g".
Assim, em Haskell, f ∘ g, ou f composto com g, pode ser escrito:
f . g
A composição é associativa, o que significa que f (g (h (x))), escrita com o operador de composição, pode deixar de fora os parênteses sem qualquer ambigüidade.
Ou seja, como (f ∘ g) ∘ h é equivalente af ∘ (g ∘ h), podemos simplesmente escrever f ∘ g ∘ h.
Circulando de volta
Voltando à nossa simplificação anterior, isto:
sumEuler = sum . map_euler . mkList
apenas significa que sumEuler
é uma composição não aplicada dessas funções:
sumEuler = \x -> sum (map_euler (mkList x))