All you need here is the following three “laws” of operator sections:
(a `op` b) = (a `op`) b = (`op` b) a = op a b
(1) (2) (3)
so that the operand goes into the free slot near the operator.
For (.)
this means that: (a . b) = (a .) b = (. b) a = (.) a b
. So,
f (g x) y !! n
= (!!) (f (g x) y) n by (3)
= ((!!) . f (g x)) y n
= ((!!) . (f . g) x) y n
= ((!!) .) ((f . g) x) y n by (1)
= (((!!) .) . (f . g)) x y n
= (((!!) .) . f . g) x y n
You should only do as much pointfree transformation as you’re comfortable with, so that the resulting expression is still readable for you – and in fact, clearer than the original. The “pointfree” tool can at times produce unreadable results.
It is perfectly OK to stop in the middle. If it’s too hard for you to complete it manually, probably it will be hard for you to read it, too.
((a .) . b) x y = (a .) (b x) y = (a . b x) y = a (b x y)
is a common pattern that you will quickly learn to recognize immediately. So the above expression can be read back fairly easily as
(!!) ((f . g) x y) n = f (g x) y !! n
considering that (.)
is associative:
(a . b . c) = ((a . b) . c) = (a . (b . c))