I do not think that there is one self-application function that will work for all terms in Haskell. Self-application is a peculiar thing in the typed calculus of lambda, which often avoids typing. This is due to the fact that with the help of self-application we can express a fixed-point combinator that introduces inconsistencies into the type system if we consider them as a logical system (see Curry-Howard Correspondence).
You asked to apply it to id function. In a native id id application, two id have different types. More explicitly, this is (id :: (A -> A) -> (A -> A)) (id :: A -> A) (for any type A ). We could do a self-application specifically designed for the id function:
sa :: (forall a. a -> a) -> b -> b sa f = ff ghci> :t sa id sa id :: b -> b
which works just fine, but pretty limited by its type.
Using RankNTypes , you can make families of self- RankNTypes functions like this, but you cannot make a general self-application function so that sa t well typed iff tt (at least not in System Fω ("F-omega"), on which GHC core calculus is based).
The reason, if you formally (possibly) work it out, is that then we could get sa sa , which does not have a normal shape, and Fω, as you know, normalizes (until we add fix , of course).
luqui source share