My attempt is currently like this: if I had (.) const const
. First
(.) const ::
(b→c)→((a→b)→(a→c)) (a→(b→a)) =
(b→c)→((a→b)→(a→c)) (b→(d→b)) = -- (1) See below question
(a→b)→(a→(d→b)) = -- substitute (b→c) by (b→(d→b))
Next
(.) const const ::
(a→b)→(a→(d→b)) (a→(b→a)) =
(a→b)→(a→(d→b)) (a→(e→a)) = -- (1) See below question
a→(d→(e→a)) -- substitute (a→b) by (a→(e→a)
Knowing the result of function composition seems like hugely productive skill if someone is programming in FP language.
Here's how I do it mentally.
I have a function of type x->y
and a function of type z->t
. If I want to compose them, y
and z
must be the same type, and the result will be of type x->t
.
For const . const
both functions have type a -> (b -> a)
, but I need to rename variables in order to avoid clashes. So I have a->(b->a)
and c->(d->c)
. Now c
is the same as b->a
. I substitute the latter in the second type, and the final result is a->d->b->a
.