Haskell Language
Состав функции
Поиск…
замечания
Оператор композиции функций (.)
Определяется как
(.) :: (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) ) )
Тип (b -> c) -> (a -> b) -> (a -> c)
можно записать в виде (b -> c) -> (a -> b) -> a -> c
так как ->
в подписях типа «связывает» вправо, соответствующие прикладной функции, связанной с левым,
f g x y z ... == (((f g) x) y) z ...
Таким образом, «поток данных» находится справа налево: x
«идет» в g
, результат которого переходит в f
, давая конечный результат:
(.) 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
....
Синтаксически все одно и то же:
(.) f g x = (f . g) x = (f .) g x = (. g) f x
который легко понять как «три правила секций оператора », где «отсутствующий аргумент» просто входит в пустой слот рядом с оператором:
(.) f g = (f . g) = (f .) g = (. g) f
-- 1 2 3
x
, находящийся по обе стороны от уравнения, можно опустить. Это известно как eta-сокращение. Таким образом, простой способ записать определение состава функции - это просто
(f . g) x = f (g x)
Это, конечно, относится к «аргументу» x
; всякий раз, когда мы пишем только (f . g)
без x
он известен как стиль без точек.
Композиция справа налево
(.)
позволяет нам составлять две функции, подавая выход одного в качестве входа в другой:
(f . g) x = f (g x)
Например, если мы хотим сместить преемника входного числа, мы можем написать
((^2) . succ) 1 -- 4
Существует также (<<<)
который является псевдонимом (.)
. Так,
(+ 1) <<< sqrt $ 25 -- 6
Композиция слева направо
Control.Category
определяет (>>>)
, который, когда специализирован для функций, является
-- (>>>) :: 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)
Пример:
sqrt >>> (+ 1) $ 25 -- 6.0
Композиция с бинарной функцией
Регулярная композиция работает для унарных функций. В случае двоичного кода мы можем определить
(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
Таким образом, (f .: g) = ((f .) . g)
по eta-сокращению, и, кроме того,
(.:) f g = ((f .) . g)
= (.) (f .) g
= (.) ((.) f) g
= ((.) . (.)) f g
так что (.:) = ((.) . (.))
, полуизвестное определение.
Примеры:
(map (+1) .: filter) even [1..5] -- [3,5]
(length .: filter) even [1..5] -- 2