Note [Excess polymorphism and join points]
In principle, if a function would be a join point except that it fails the polymorphism rule (see Note [The polymorphism rule of join points] in GHC.Core), it can still be made a join point with some effort. This is because all tail calls must return the same type (they return to the same context!), and thus if the return type depends on an argument, that argument must always be the same. For instance, consider: let f :: forall a. a -> Char -> [a] f @a x c = ... f @a y 'a' ... in ... f @Int 1 'b' ... f @Int 2 'c' ... (where the calls are tail calls). `f` fails the polymorphism rule because its return type is [a], where [a] is bound. But since the type argument is always 'Int', we can rewrite it as: let f' :: Int -> Char -> [Int] f' x c = ... f' y 'a' ... in ... f' 1 'b' ... f 2 'c' ... and now we can make f' a join point: join f' :: Int -> Char -> [Int] f' x c = ... jump f' y 'a' ... in ... jump f' 1 'b' ... jump f' 2 'c' ... It's not clear that this comes up often, however. TODO: Measure how often and add this analysis if necessary. See #14620. ************************************************************************ * * \subsection{Sequencing on types} * * ************************************************************************
References 1
- The polymorphism rule of join points GHC.Core
Referenced by 1
- GHC.Core.Type call site