2012-01-11 37 views
5

Trong mã này, tôi đang cố gắng để có tham số đầu tiên trong chức năng công nhân của tôi go là kiểu 'gia đình kiểu'. Tôi thấy rằng trong các loại type families documentation một chức năng tương tự insert thuộc về loại lớp, trong khi trong ví dụ của tôi dưới đây nó không.'Biến loại mơ hồ `a` trong ràng buộc' có nghĩa là gì?

Tôi mới làm quen với các gia đình nên có thể tôi đang sử dụng sai, nhưng lỗi này có nghĩa là gì?

{-# LANGUAGE TypeFamilies #-} 

-- | key 
class K a where 
    -- | iterator for key 
    type I a :: * 
    mkI :: a -> I a 

--| A map 
data (K a) => M a b = M a b 

insert :: (K a) => a -> b -> M a b -> M a b 
insert = go mkI -- <<< PROBLEM 
    where 
    go o a b m = m 

mơ hồ kiểu biến 'một' trong chế:

`K a' 

    arising from an expression type signature at Data/Map2.hs:167:10-33 

sửa chữa dự kiến: thêm một chữ ký kiểu đó sửa chữa những kiểu biến (s)

+3

Trước hết, lưu ý rằng bối cảnh datatype ('dữ liệu (K a) => M a b = M a b') đã bị xóa khỏi ngôn ngữ và không bao giờ hữu ích. Nhìn vào những thứ khác ngay bây giờ. –

Trả lời

10

biên dịch này :

{-# LANGUAGE TypeFamilies, GADTs, ScopedTypeVariables #-} 

-- | key 
class K a where 
    -- | iterator for key 
    type I a :: * 
    mkI :: a -> I a 

-- | A map 
data M x y where 
    M :: K a => a -> b -> M a b 

insert :: forall a b. (K a) => a -> b -> M a b -> M a b 
insert = go mkI 
    where 
    go :: (a -> I a) -> a -> b -> M a b -> M a b 
    go o a b m = m 

Tôi đã thay đổi gì và tại sao? Trước tiên, tôi giả định rằng bạn muốn có ràng buộc trên M, vì vậy tôi đã sử dụng một dạng định nghĩa kiểu thực thi ràng buộc và làm cho nó có sẵn tại các trang web sử dụng, GADT.

Thứ hai, vấn đề mà GHC của bạn đã phàn nàn, sự mơ hồ. Vấn đề là không có cách nào để trình biên dịch suy ra mkI nó nên sử dụng, vì vậy chúng ta phải nói với nó. Để làm được điều đó, chúng ta phải mang các biến kiểu được sử dụng vào phạm vi và sau đó cho trình biên dịch biết chữ ký cục bộ có thể sử dụng loại nào.

+0

Xin chào, Bạn sẽ làm thế nào để "chuyển" chức năng cấp cao nhất? – cdupont

+0

@cdupont Bạn chỉ có thể di chuyển nó lên cấp cao nhất và thêm ràng buộc vào chữ ký kiểu, 'go :: (K a) => (a -> I a) -> a -> b -> M ab -> M ab'. Mặc dù vậy, tôi không thấy cái gì sẽ hữu ích. –

+0

Trong trường hợp này, 'a' và' b' trong 'chèn' sẽ khác trong' go' ... Đó là lý do bạn thêm forall không? – cdupont

Các vấn đề liên quan