Clinton
Clinton

Reputation: 23135

ScopedTypeVariables doesn't bring type variables into scope

Here's a simple function to return the alignment of a pointer:

{-# LANGUAGE ScopedTypeVariables #-}

import Foreign.Ptr (Ptr)
import Foreign.Storable (Storable, alignment)

main = return ()

ptrAlign1 :: (Storable a) => Ptr a -> Int
ptrAlign1 _ = alignment (undefined :: a) 

But I get the following error:

Could not deduce (Storable a0) arising from a use of `alignment'
from the context (Storable a)
  bound by the type signature for
             ptrAlign1 :: Storable a => Ptr a -> Int
  at prog.hs:8:14-41
The type variable `a0' is ambiguous

If I rewrite ptrAlign in a more messy faction like so:

ptrAlign2 :: (Storable a) => Ptr a -> Int
ptrAlign2 = ptrAlign3 undefined where
  ptrAlign3 :: (Storable a) => a -> Ptr a -> Int
  ptrAlign3 x _ = alignment x

It works fine (of course this version doesn't even need ScopedTypeVariables).

But I'm still curious about why the first version is throwing an error, and what can be done to resolve it?

Upvotes: 7

Views: 364

Answers (1)

Cactus
Cactus

Reputation: 27636

Even with ScopedTypeVariables turned on, type variables are not put in scope unless you explicitly quantify them, i.e.

ptrAlign1 :: forall a. (Storable a) => Ptr a -> Int
ptrAlign1 _ = alignment (undefined :: a) 

Upvotes: 10

Related Questions