I don't think there is a single self-application function that will work for all terms in Haskell. Self-application is a peculiar thing in typed lambda calculus, which will often evade typing. This is related to the fact that with self-application we can express the fixed-point combinator, which introduces inconsistencies into the type system when viewed as a logical system (see Curry-Howard correspondence).
You asked about applying it to the id function. In the self application id id, the two ids have different types. More explicitly it's (id :: (A -> A) -> (A -> A)) (id :: A -> A) (for any type A). We could make a self-application specifically designed for the id function:
sa :: (forall a. a -> a) -> b -> b
sa f = f f
ghci> :t sa id
sa id :: b -> b
which works just fine, but is rather limited by its type.
Using RankNTypes you can make families of self-application functions like this, but you're not going to be able to make a general self-application function such that sa t will be well-typed iff t t is well-typed (at least not in System Fω ("F-omega"), which GHC's core calculus is based on).
The reason, if you work it out formally (probably), is that then we could get sa sa, which has no normal form, and Fω is known to be normalizing (until we add fix of course).
sashould have? Remember that all terms in Haskell must have a type. Also, what problem are you trying to solve?