Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 789
Clinton Avatar asked Dec 01 '15 03:12

Clinton


1 Answers

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) 
like image 101
Cactus Avatar answered Sep 28 '22 15:09

Cactus