This is a partial application of the composition operator to the composition operator itself. In general, we know that if we apply (.)
to some function f :: x -> y
, then
>>> :t (.) f
(.) f :: (a -> x) -> a -> y
because of how the types line up:
(b -> c) -> (a -> b) -> a -> c
x -> y
--------------------------------
(a -> x) -> a -> y
We drop the first argument, and replace remaining occurrences of b
and c
with the corresponding types of the given argument.
Here, f
is just (.)
again, meaning we identify x ~ (b -> c)
and y ~ (a -> b) -> a -> c
. Lining up the types again
(a -> x ) -> a -> y
b -> c (a -> b) -> a -> c
Since a
occurs on the top and the bottom, we need to pick a new variable name for a
on the bottom; GHC chose a1
:
(a -> x ) -> a -> y
b -> c (a1 -> b) -> a1 -> c
Putting the two together yields the type you see in GHCi.
(a -> b -> c) -> a -> (a1 -> b) -> a1 -> c
Anatomy jokes aside, what is (.)(.)
?
Let's say you have a function f :: a -> b
, but you want a function g :: a -> c
, that is, you want f
but with a different return type. The only thing you can do is find a helper function h :: b -> c
that will convert the return value for you. Your function g
is then simply the composition of h
and f
:
g = h . f
You might, however, have a more general function h' :: t -> b -> c
, which can
turn values of type b
into values of type c
in multiple ways, depending on the value of some argument x :: t
. Then you could get lots of different g
s depending on that argument.
g = (h' x) . f
Now, given h'
, x
, and f
, we can return our g
, so let's write a function that does that: a function that "promotes" the return value of f
from a value of type b
to a value of type c
, given a function h'
and some value x
:
promote h' x f = (h' x) . f
You can mechanically convert any function to point-free form; I'm not familiar with the details, but using PointFree.io produces
promote = ((.) .)
which is just the partial application (.) (.)
written as a section, that is:
((.) (.)) h' x f == (h' x) . f
So, our "boobs" operator is just a generalized pre-composition operator.