I can agree that for a functional language, being able to apply any reasonable
function to any reasonable matching argument has to be doable, but such a
fundamental operation surely needs to be simple to describe?
But it is already rather simple conceptually, it's just that Haskell's kind signature syntax makes it look hairy. I mean, if you squint enough, this:
($) :: forall (r :: RuntimeRep) (a :: *) (b :: TYPE r). (a -> b) -> a -> b
could be written like:
($) :: RuntimeRep r => (a :: TYPE Lifted) (b :: TYPE r). (a -> b) -> a -> b