2015-12-01 17 views
7

Dưới đây là một chức năng đơn giản để trả lại sự liên kết của một con trỏ:ScopedTypeVariables không mang lại biến kiểu vào phạm vi

{-# LANGUAGE ScopedTypeVariables #-} 

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

main = return() 

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

Nhưng tôi nhận được lỗi sau:

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 

Nếu tôi viết lại ptrAlign trong một phe lộn xộn hơn như vậy:

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

Nó hoạt động tốt (tất nhiên là phiên bản này thậm chí không cần ScopedTypeVariables).

Nhưng tôi vẫn còn tò mò về lý do tại sao phiên bản đầu tiên là ném một lỗi, và những gì có thể được thực hiện để giải quyết nó?

Trả lời

10

Ngay cả với ScopedTypeVariables bật, biến kiểu không được đưa vào phạm vi, trừ khi bạn xác định số lượng họ một cách rõ ràng, ví dụ:

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

lý do đằng sau này là gì? –

+0

@ErikAllik: [Hướng dẫn] (https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/other-type-extensions.html#scoped-type-variables) không nói, nhưng Tôi hy vọng nó để mã hiện tại không có hành vi của nó thay đổi chỉ đơn giản bằng cách bật 'ScopedTypeVariables'. –