Search code examples
haskellcurryinglambda-calculusfunction-composition

What is the type of this haskell double function composition?


t2 = (\x y z-> x.y.x)

GHCI shows me this:

t2 :: (b1 -> b2) -> (b2 -> b1) -> p -> b1 -> b2

I can't quite grasp it how this type signature comes to be. So far I've figured that the righter-most x is basically a function which takes a b2 and returns a b1, then that b1 is the input of the middle function y, and outputs b2again? Should it not return a value of a new type b3or something?


Solution

  • First let's rewrite this in a way that makes it clear which argument corresponds to which part of the type signature:

    t2 :: (b1->b2) -> (b2->b1) -> p -> b1 -> b2
    t2    x           y           z  = x . y . x
    

    z :: p isn't used at all, so we can easily eliminate this by instead considering

    t3 :: (b1->b2) -> (b2->b1) -> b1 -> b2
    t3    x           y         = x . y . x
    

    Why is that the type? Well, the composition chain feeds the result of x into y, and the result of y back into x. In other words, y gets you from the result type of x back to the argument type of x. Therefore the type of y must be the “inverted” type of x. So

    t3 :: (m->n) -> (n->m) -> ?
    t3    x         y       = x . y . x
    

    The type of the composition is dominated by the “outer ends”, i.e. the argument must be the type of argument for x and the result must be the type of result of... again, x. Hence

    t3 :: (m->n) -> (n->m) -> m->n
    t3    x         y       = x.y.x
    

    which is what GHCi told you, with renamed type variables.