2011-09-23 27 views
8

Tôi chỉ tò mò tại sao tôi phải viết những dòng này,lời giải thích cho "loại bất hợp pháp gia đình đồng nghĩa"

instance (HzMonad , Data.Suitable.Suitable α, γ ~ ExprTyp α) => VarDecl γ where 
    var = varhz 

thay vì điều này

instance (HzMonad , Data.Suitable.Suitable α) => VarDecl (ExprTyp α) where 
    var = varhz 

-- error 
Hz2/Language.hs:114:53: 
    Illegal type synonym family application in instance: ExprTyp α 
    In the instance declaration for `VarDecl (ExprTyp α)' 

nơi

varhz :: 
    (HzMonad , Data.Suitable.Suitable α) => 
    String -> ExprTyp α -> (ExprTyp α) 

là gì dấu ngã chưa? Cảm ơn rất nhiều.

+3

Tôi không có năng lượng (tối nay) để đánh giá câu trả lời đầy đủ, nhưng câu trả lời ngắn gọn là đây là một ví dụ khác về các giả định sâu sắc về những thứ loại cấp đang được chuyển thành sai khi gõ gia đình được thêm vào hỗn hợp. Dấu ngã là xác nhận bình đẳng kiểu. –

+0

Ah, tôi hiểu ngay bây giờ, không có vấn đề gì. Cảm ơn bạn đã lưu ý. Làm thế nào để có được xung quanh nó là một câu chuyện khác, mà tôi vẫn đang cố gắng tìm ra. – gatoatigrado

Trả lời

2

Tôi nghĩ rằng vấn đề là mọi thứ ở bên phải của => phải là trình tạo kiểu hoặc biến kiểu. ExprTyp có thể ám chỉ đến nhiều hàm tạo kiểu differet. Thay thế điều này bằng một ràng buộc bình đẳng sẽ thực sự hoạt động, nhưng cá thể kết quả sẽ vô hiệu, vì trình biên dịch sẽ không thể suy ra bất cứ điều gì về γ cho rằng đó là một ExprTyp - ExprTyp có thể được đặt bí danh cho bất kỳ thứ gì.

Trong trường hợp của tôi - Tôi đang cố gắng viết một đơn nguyên DSL - giải pháp là bao bọc tất cả các công dụng của kiểu được liên kết trong một hàm tạo newtype. Ví dụ, nếu chúng ta bắt đầu với,

class MyDSL m a where 
    type ExprTyp m :: * -> * 
    printE :: ExprTyp m a -> m() 

sau đó gói này sẽ dẫn đến

newtype ExprT a = ExprT a 
class MyDSL m a where 
    type ExprTyp m :: * -> * 
    printE :: ExprT (ExprTyp m a) -> m() 

Sau đó, ví dụ, khai báo biến (tôi đang viết mã cho khai báo biến tupled) có thể là,

instance (HzMonad , Data.Suitable.Suitable α, γ ~ ExprTyp α) => VarDecl (ExprT γ) 
instance (Monad , VarDecl α, VarDecl β) => VarDecl (α, β) 

vui lòng đăng nhận xét nếu có điều gì đó không rõ ràng.

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