ScopedTypeVariables let you refer to universally quantified types inside of a declaration. To be more explicit:
import Data.Monoid foo :: forall a b c. (Monoid b, Monoid c) => (a, b, c) -> (b, c) -> (a, b, c) foo (a, b, c) (b', c') = (a :: a, b'', c'') where (b'', c'') = (b <> b', c <> c') :: (b, c)
The important thing is that we can use
c to instruct the compiler in subexpressions of the declaration (the tuple in the
where clause and the first
a in the final result). In practice,
ScopedTypeVariables assist in writing complex functions as a sum of parts, allowing the programmer to add type signatures to intermediate values that don't have concrete types.