スタック・オーバーフローに参加する
682万人以上のプログラマーが集まるスタック・オーバーフローに参加しませんか?
簡単な登録後、すぐにご利用いただけます。
登録

Why does this code require the ScopedTypeVariables extension?

{-# LANGUAGE ScopedTypeVariables #-}

char = case Just '3' of 
    Just (x :: Char) -> x
    Nothing          -> '?'

When I read the documentation on ScopedTypeVariables, it seems to mean unifying type variables in the function body with the parent function signature. This code snippet isn't unifying any type variables though!

Also what is the effect of loading ScopedTypeVariables without also loading ExplicitForAll? All the other usecases of ScopedTypeVariables seem to require ExplicitForAll to actually work. But in the above snippet, there's no ExplicitForAll.

share|improve this question
up vote 4 down vote accepted

ScopedTypeVariables enables ExplicitForAll automatically For the sake of your sanity I would suggest always using ScopedTypeVariables when using any other type system extensions (except possibly the ones dealing only with classes/instances/contexts) and never using ExplicitForAll directly.

The reason ScopedTypeVariables is required for pattern variable signatures is just that such signatures are part of the extension. Among other uses, they give you a way to bring a type variable into scope. For example:

f (Just (x::a)) = bob
  where
    bob::[a]
    bob = [x]

I do not know why the pattern signatures are part of ScopedTypeVariables, per se; most likely they were created for this purpose, and all the code was written in one go. Teasing them apart to make orthogonal extensions was almost certainly considered more trouble than it was worth.

Edit

Actually, there's a pretty good reason. With the exception of pattern bindings, a type variable in a pattern signature is generalized, bringing that variable into scope. So in the above example, you don't need to know if there is an a in the outer type environment. If you could enable pattern signatures without scoped type variables, then the variable could be generalized or not depending on whether scoped type variables were turned on or not. The same sort of confusion happens for ExplicitForAll without ScopedTypeVariables, which is why I'd like to kill that extension and make ScopedTypeVariables the default, or at least turn it on automatically with the extensions that currently enable ExplicitForAll.

share|improve this answer
    
Why do pattern variable signatures need ScopedTypeVariables though? Was it just not possible until the extension came along? They seem orthogonal in this case because there's no unification of any type variables, since there is no type variables in the expression. – CMCDragonkai Apr 1 '15 at 15:59
    
@CMCDragonkai, see my edit. I doubt there's a very deep reason, but I don't really know. – dfeuer Apr 1 '15 at 16:05
    
I see. In your example, is a inferred to be universally quantified? Or is a brought from somewhere else? – CMCDragonkai Apr 1 '15 at 16:09
    
@CMCDragonkai With the extension, the pattern (x :: a) literally defines a in its scope to be whatever the type of x is. – Ørjan Johansen Apr 1 '15 at 16:13
2  
Actually GHC 6.8.1, which was the first release to have the LANGUAGE pragma system, had both ScopedTypeVariables and PatternSignatures. The latter was removed from the docs in 7.0.1, although you can still supply it and get a deprecation warning telling you to use ScopedTypeVariables instead. – Ørjan Johansen Apr 1 '15 at 16:30

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.