Точка оператора в Хаскеле
Я пытаюсь понять, что делает оператор точки в этом коде Haskell:
sumEuler = sum . (map euler) . mkList
Краткий ответ
Эквивалентный код без точек, то есть просто
sumEuler = \x -> sum ((map euler) (mkList x))
или без лямбды
sumEuler x = sum ((map euler) (mkList x))
потому что точка (.) Указывает на состав функции.
Более длинный ответ
Во-первых, давайте упростим частичное применение euler
к map
:
map_euler = map euler
sumEuler = sum . map_euler . mkList
Теперь у нас есть только точки. На что указывают эти точки?
Из источника :
(.) :: (b -> c) -> (a -> b) -> a -> c
(.) f g = \x -> f (g x)
Таким образом (.)
является оператором compose .
Создать
В математике мы могли бы написать композицию функций f (x) и g (x), то есть f (g (x)), как
(f ∘ g) (x)
, который можно прочитать как "f, составленный с помощью g".
Таким образом, в Haskell, f ∘ g или f, составленные с помощью g, могут быть записаны:
f . g
Композиция является ассоциативной, что означает, что f (g (h (x))), записанная с помощью оператора композиции, может оставить скобки без какой-либо двусмысленности.
То есть, поскольку (f ∘ g) ∘ h эквивалентно f ∘ (g ∘ h), мы можем просто написать f ∘ g ∘ h.
по кругу назад
Возвращаясь к нашему более раннему упрощению, это:
sumEuler = sum . map_euler . mkList
просто означает, что sumEuler
является непримененной композицией этих функций:
sumEuler = \x -> sum (map_euler (mkList x))