2015-12-01 3 views
7

Hier ist eine einfache Funktion, die Ausrichtung eines Zeigers zurück:ScopedTypeVariables nicht Typvariablen in Umfang bringen

{-# LANGUAGE ScopedTypeVariables #-} 

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

main = return() 

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

Aber ich erhalte den folgenden Fehler:

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 

Wenn ich ptrAlign umschreiben in eine unordentlichere Fraktion wie folgt:

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

Es funktioniert gut (natürlich diese Version braucht nicht einmal ScopedTypeVariables).

Aber ich bin immer noch neugierig, warum die erste Version einen Fehler wirft, und was kann getan werden, um es zu lösen?

Antwort

10

Auch bei ScopedTypeVariables eingeschaltet, geben Sie Variablen sind in ihrem Umfang nicht setzen, wenn Sie sie explizit quantifizieren, das heißt

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

was ist die Logik dahinter? –

+0

@ErikAllik: [Das Handbuch] (https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/other-type-extensions.html#scoped-type-variables) sagt nicht, aber Ich erwarte, dass sich das Verhalten des vorhandenen Codes nicht ändert, indem einfach "ScopedTypeVariables" aktiviert wird. –