
G'day all. Ketil Malde wrote:
(.) . (.) .(.)
I entered it into GHCi, and got
:: forall a a b c a. (b -> c) -> (a -> a -> a -> b) -> a -> a -> a -> c
I got this:
Prelude> :t (.) . (.) . (.)
(.) . (.) . (.) :: forall a a1 b c a2.
(b -> c) -> (a -> a1 -> a2 -> b) -> a -> a1 -> a2 -> c
Quoting Tim Docker
Is there a straightforward technique by which type signatures can be "hand calculated", or does one end up needing to run the whole inference algorithm in one's head?
For this case, yes, but you need to expand the point-free style first. Using the combinator B to represent (.): (.) . (.) . (.) = \f -> B (B (B f)) = \f g x -> B (B (B f)) g x = \f g x -> B (B f) (g x) = \f g x y -> B (B f) (g x) y = \f g x y -> B f (g x y) = \f g x y z -> f (g x y z) The type should now be obvious. However, it's probably easier in this case to get the expanded lambda expression directly from the type's "free theorem". Cheers, Andrew Bromage