2011-12-31 5 views
8

Sau đây không biên dịch:Template Haskell tờ khai dữ liệu mà lấy Hiện

import Language.Haskell.TH 
makeAlpha n = [d| data Alpha = Alpha $(conT n) deriving (Show, Read) |] 

Tôi không thể làm ra những gì lỗi nghĩa ở tất cả:

Can't derive instances where the instance context mentions 
type variables that are not data type parameters 
    Offending constraint: Show t_d 
When deriving the instance for (Show Alpha) 
In the Template Haskell quotation 
    [d| data Alpha = Alpha $(conT n) deriving (Show, Read) |] 
In the expression: 
    [d| data Alpha = Alpha $(conT n) deriving (Show, Read) |] 

Có thể làm Mục từ như thế này?

+0

Tôi nghĩ rằng vấn đề có thể là nó đang cố gắng tìm ra các trường hợp trước khi nó được * n *; tức là nó đang cố mở rộng mối nối của bạn để chứa các thể hiện, nhưng không thể, bởi vì nó không biết '$ (conT n)' trông như thế nào. Không chắc chắn mặc dù. – ehird

+0

Tôi nghĩ tương tự, nhưng tôi thường không thể chắc chắn những gì được cho phép và không với mẫu Haskell ... Trong kịch bản này, tôi nghĩ rằng nó rõ ràng nó không thể lấy được các trường hợp nào và cần phải chờ đợi cho việc sử dụng các chức năng để mở rộng . Đây có phải là một lỗi? – Ana

+0

Hmm, đợi đã, không phải là 'dữ liệu Alpha = $ (conT n) 'hay gì đó? Tôi nghĩ rằng những gì bạn có bây giờ là một lỗi kiểu, ít nhất là từ liếc nhìn [định nghĩa của 'Dec'] (http://hackage.haskell.org/packages/archive/template-haskell/2.6.0.0/doc/html /Language-Haskell-TH-Syntax.html#t:Dec). – ehird

Trả lời

7

Vấn đề này phát sinh do TH trích dẫn là loại kiểm tra khi chúng được biên soạn, với các mối nối được thay thế bằng các biến. Điều này thường là một ý tưởng tốt, bởi vì nó cho phép nhiều loại vấn đề được phát hiện trước khi ghép nối được chạy, nhưng trong một số trường hợp, điều này có thể làm cho trình biên dịch từ chối sai một mối nối có thể tạo ra mã hợp lệ.

Trong trường hợp này, điều này có nghĩa rằng trình biên dịch sẽ cố gắng để kiểm tra mã này:

data Alpha = Alpha t deriving (Show, Read) 

này không làm việc vì có nguồn gốc ShowRead trường hợp cần phải sử dụng ShowRead cho t, nhưng kể từ khi t không phải là tham số kiểu của Alpha, nó không thể thêm các ràng buộc cần thiết. Tất nhiên, khi mối nối này được chạy, t được thay thế bằng loại bê tông, vì vậy các trường hợp thích hợp sẽ có sẵn mà không cần bất kỳ ràng buộc nào, vì vậy đây là một trong những trường hợp trình biên dịch quá thận trọng.

Cách giải quyết là không sử dụng trích dẫn, nhưng thay vào đó hãy sử dụng bộ kết hợp TH, không phải chịu các kiểm tra bổ sung này. Đó là lộn xộn, nhưng nó hoạt động:

Đã có some talk about relaxing the checks done on quotes, nhưng bây giờ bạn sẽ chỉ phải đối phó với nó.