2011-09-27 3 views
11

Tôi đang cố gắng tạo vòng Z/n (như số học bình thường, nhưng modulo một số số nguyên). Ví dụ mẫu là Z4:Hàm tạo dữ liệu trong mẫu haskell

instance Additive.C Z4 where 
    zero = Z4 0 
    (Z4 x) + (Z4 y) = Z4 $ (x + y) `mod` 4 

Và cứ như vậy cho vòng. Tôi muốn có thể nhanh chóng tạo ra những điều này, và tôi nghĩ rằng cách để làm điều đó là với mẫu haskell. Lý tưởng nhất là tôi muốn chỉ cần đi $(makeZ 4) và nó nhổ ra mã cho Z4 như tôi đã xác định ở trên.

Tôi đang gặp nhiều rắc rối với điều này. Khi tôi làm genData n = [d| data $n = $n Integer] tôi nhận được "lỗi phân tích cú pháp trong khai báo dữ liệu/newtype". Nó hoạt động nếu tôi không sử dụng các biến mặc dù: [d| data Z5 = Z5 Integer |], điều đó có nghĩa là tôi đang làm điều gì đó kỳ lạ với các biến. Tôi không chắc chắn những gì mặc dù; Tôi đã thử xây dựng chúng thông qua newName và điều đó dường như không hoạt động.

Có ai có thể giúp tôi với những gì đang xảy ra ở đây không?

+0

Tôi không phải là Trình hướng dẫn mẫu Haskell, nhưng tôi cá cược những người sẽ muốn xem mã Haskell mẫu của bạn. –

Trả lời

13

Template Haskell documentation liệt kê những thứ bạn được phép ghép nối.

Một mối nối có thể xảy ra ở vị trí của

  • một biểu thức; biểu thức ghép phải có loại Q Exp
  • một loại; biểu thức ghép phải có loại Q Typ
  • danh sách các khai báo cấp cao nhất; biểu thức ghép phải có loại Q [Dec]

Trong cả hai lần xuất hiện của $n, tuy nhiên, bạn đang cố gắng để ghép một tên.

Điều này có nghĩa là bạn không thể thực hiện việc này bằng cách sử dụng trích dẫn và kết nối. Bạn sẽ phải xây dựng việc khai báo bằng cách sử dụng các bộ kết hợp khác nhau có sẵn trong mô-đun Language.Haskell.TH.

Tôi nghĩ điều này phải tương đương với những gì bạn đang cố gắng làm.

genData :: Name -> Q [Dec] 
genData n = fmap (:[]) $ dataD (cxt []) n [] 
          [normalC n [strictType notStrict [t| Integer |]]] [] 

Đúng, có chút xấu xí, nhưng có bạn. Để sử dụng, hãy gọi tên đó bằng tên mới, ví dụ:

$(genData (mkName "Z5")) 
+0

Bạn có thể bao gồm một ví dụ về việc sử dụng nó không? Tôi sửa đổi những gì bạn đã có một chút và chỉ cần ném '$ (genData" Foo ")' như là một cấp cao nhất vào mã của tôi, nhưng nếu tôi làm ': i Foo' trong ghci nó không tìm thấy bất cứ điều gì. – Xodarap

+1

@Xodarap: Sử dụng 'mkName' để tạo một' Tên' từ một 'Chuỗi'. Tôi đã thêm một ví dụ. Tôi đoán bạn có thể đã sử dụng 'newName', thêm một số thứ ở cuối để đảm bảo rằng tên là duy nhất, vì vậy': info' sẽ không hiển thị nó. Bạn sẽ có thể nhìn thấy nó bằng cách sử dụng ': trình duyệt', mặc dù. – hammar

+0

Xin cảm ơn! đây chính là vấn đề của tôi. – Xodarap