(.) . (.) (.) . (.) is the composition of the composition operator with itself.
If we look at
((.) . (.)) fgx
we can appreciate that a few steps, first in parentheses,
((((.) . (.)) f) g) x
then we apply using (foo . bar) arg = foo (bar arg) :
~> (((.) ((.) f)) g) x ~> (((.) f) . g) x ~> ((.) f) (gx) ~> f . gx
More principled,
(.) :: (b -> c) -> (a -> b) -> (a -> c)
So, using (.) As the first argument (.) , We have to combine
b -> c
from
(v -> w) -> (u -> v) -> (u -> w)
This gives
b = v -> w c = (u -> v) -> (u -> w)
and
(.) (.) = ((.) .) :: (a -> v -> w) -> a -> (u -> v) -> (u -> w)
Now, to apply this to (.) , We need to unify the type
a -> v -> w
with type (.) after renaming
(s -> t) -> (r -> s) -> (r -> t)
what gives
a = s -> t v = r -> s w = r -> t
and therefore
(.) . (.) :: (s -> t) -> (u -> r -> s) -> (u -> r -> t)
and of the type by which we can (almost) assume that (.) . (.) (.) . (.) applies a function (of one argument) to the result of a function of two arguments.
Daniel Fischer
source share