I believe I understand fmap . fmap
for Functors, but on functions it\'s hurting my head for months now.
I\'ve seen that you can just apply the definitio
So, this is what I get when I do a slightly more incremental expansion
(.) f g = \x -> f (g x)
(.) . g = \x -> (.) (g x)
= \x -> \y -> (.) (g x) y
= \x -> \y -> \z -> (g x) (y z)
= \x y z -> (g x) (y z)
(.) . (.) = \x y z -> ((.) x) (y z)
= \x y z -> \k -> x (y z k)
= \x y z k -> x (y z k)
Which, according to ghci has the correct type
Prelude> :t (.) . (.)
(.) . (.) :: (b -> c) -> (a -> a1 -> b) -> a -> a1 -> c
Prelude> :t \x y z k -> x (y z k)
\x y z k -> x (y z k)
:: (t1 -> t) -> (t2 -> t3 -> t1) -> t2 -> t3 -> t
Prelude>
While I don't know the origins of this combinator, it is likely that it was developed for use in combinatory logic, where you work strictly with combinators, so you can't define things using more convenient lambda expressions. There may be some intuition that goes with figuring these things out, but I haven't found it. Most likely, you would develop some level of intuition if you had to do it enough.