Reputation: 23135
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
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