In the following snippet (I have abstracted all other trivial parts)
data T s = T (s -> s)
foo :: T s -> s -> s
foo (T f) x = bar x where
bar :
ScopedTypeVariables are indeed the solution, but there's an extra requirement to use them: You must put explicit foralls in the type signatures declaring the variables you want to scope, like this:
foo :: forall s. T s -> s -> s
This is so that the meaning of signatures in code doesn't depend on whether the extension is enabled or not.