Reputation: 5118
The following code (which is not meant to do anything useful) compiles fine :
{-# LANGUAGE ScopedTypeVariables #-}
import System.Random
uselessFunction :: (RandomGen g) => g -> [Int]
uselessFunction gen =
let (value::Int, newGen) = (random gen)
in (uselessFunction newGen)
Is it possible for me to use type variables in the pattern matching, in the following spirit (code fails to compile):
{-# LANGUAGE ScopedTypeVariables #-}
import System.Random
uselessFunction :: (RandomGen g, Random a) => g -> [a]
uselessFunction gen =
let (value::a, newGen) = (random gen)
in (uselessFunction newGen)
Upvotes: 4
Views: 253
Reputation: 27636
The real way out of this is described in Type Variables in Patterns, by Richard A. Eisenberg, Joachim Breitner, Simon Peyton Jones:
For many years, GHC has implemented an extension to Haskell that allows type variables to be bound in type signatures and patterns, and to scope over terms. This extension was never properly specified. We rectify that oversight here. With the formal specification in hand, the otherwise-labyrinthine path toward a design for binding type variables in patterns becomes blindingly clear. We thus extend ScopedTypeVariables to bind type variables explicitly, obviating the Proxy workaround to the dustbin of history.
Upvotes: 0
Reputation: 18199
You've already noticed that the ScopedTypeVariables
extension allows you to put type annotations on patterns. But for the extension's main purpose, to make a type variable be locally scoped so that you can refer to it inside the function, you must also declare it with a forall in the type declaration, like so:
uselessFunction :: forall a g. (RandomGen g, Random a) => g -> [a]
This doesn't change the meaning of the declaration itself, but hints to GHC that you may want to use the variable locally.
Upvotes: 8