> In practice, it turns out that composed types don't seem to be that hard.
Depends on what you mean by hard. Hard to read or hard to reason about?
* -> * and * -> * -> * are easy to read and reason about, i.e. Int -> Char -> Int. But what about types of types?
(* -> * ) -> * is confusing to reason about IMO. i.e. Applicative Functors:
(<$>) :: Functor f => (a -> b) -> f a -> f b
Not really intuitive at all, the only reason I can understand it is that I know what functors and Monads are.