2015-12-01 10 views
7

Ecco una semplice funzione per restituire l'allineamento di un puntatore:ScopedTypeVariables non porta variabili di tipo in ambito

{-# LANGUAGE ScopedTypeVariables #-} 

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

main = return() 

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

ma ottengo il seguente errore:

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 

Se riscrivo ptrAlign in una fazione più confusa del genere:

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

Funziona bene (ovviamente questa versione non ha nemmeno bisogno di ScopedTypeVariables).

Ma sono ancora curioso di sapere perché la prima versione sta generando un errore e cosa si può fare per risolverlo?

risposta

10

Anche con ScopedTypeVariables acceso, variabili di tipo non sono messi nella portata a meno che non quantificare esplicitamente, cioè

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

qual è la logica dietro questo? –

+0

@ErikAllik: [Il manuale] (https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/other-type-extensions.html#scoped-type-variables) non dice, ma Mi aspetto che sia così che il codice esistente non ha il suo comportamento modificato semplicemente attivando 'ScopedTypeVariables'. –

Problemi correlati