Точковий оператор у Хаскелі
Я намагаюся зрозуміти, що робить оператор крапок у цьому коді Хаскелла:
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)
Таким чином, (.)
є оператором складання .
Скласти
У математиці ми можемо записати склад функцій 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))