> But it works on concrete types, not functions.
Isn't the problem type variables, not functions?
Prelude Data.Typeable> :set -XScopedTypeVariables
Prelude Data.Typeable> let fun x = case x of {Just (i::Int) -> i + 1; Nothing -> 0}
Prelude Data.Typeable> :t fun
fun :: Maybe Int -> Int
Prelude Data.Typeable> typeOf fun
Maybe Int -> Int