2012-05-10 24 views
6

Gói mang tính xây dựng-đại số cho phép bạn xác định các trường hợp đại số module (như không gian vectơ nhưng sử dụng một chiếc nhẫn nơi một lĩnh vực được yêu cầu)Xác định một mô-đun đại số sử dụng gói mang tính xây dựng-đại số

Đây là cố gắng của tôi ở việc xác định một mô-đun :

{-# LANGUAGE MultiParamTypeClasses, TypeSynonymInstances #-} 
module A where 
import Algebra.Structures.Module 
import Algebra.Structures.CommutativeRing 
import Algebra.Structures.Group 

newtype A = A [(Integer,String)] 

instance Group A where 
    (A a) <+> (A b) = A $ a ++ b 
    zero = A [] 
    neg (A a) = A $ [((-k),c) | (k,c) <- a] 


instance Module Integer A where 
    r *> (A as) = A [(r <*> k,c) | (k,c) <- as] 
.210

Nó thất bại bởi:

A.hs:15:10: 
    Overlapping instances for Group A 
     arising from the superclasses of an instance declaration 
    Matching instances: 
     instance Ring a => Group a -- Defined in Algebra.Structures.Group 
     instance Group A -- Defined at A.hs:9:10-16 
    In the instance declaration for `Module Integer A' 

A.hs:15:10: 
    No instance for (Ring A) 
     arising from the superclasses of an instance declaration 
    Possible fix: add an instance declaration for (Ring A) 
    In the instance declaration for `Module Integer A' 
Failed, modules loaded: none. 

Nếu tôi nhận xét các trường hợp Group ra, sau đó:

A.hs:16:10: 
    No instance for (Ring A) 
     arising from the superclasses of an instance declaration 
    Possible fix: add an instance declaration for (Ring A) 
    In the instance declaration for `Module Integer A' 
Failed, modules loaded: none. 

tôi đọc này là yêu cầu một thể hiện của Ring AModule Integer A mà không có ý nghĩa và là không bắt buộc trong định nghĩa lớp học:

class (CommutativeRing r, AbelianGroup m) => Module r m where 
    -- | Scalar multiplication. 
    (*>) :: r -> m -> m 

Bạn có thể giải thích điều này không?

+1

Bạn có lo ngại rằng cá thể 'Nhóm' của bạn đối với' A' không thực sự xác định một nhóm? Ví dụ, 'let a = [(1," foo ")]', sau đó 'a <+> neg a = [(1," foo "), (- 1," foo ")]' không giống như 'zero'. –

+0

Vâng, tôi biết. Ý tưởng ban đầu là giảm 'a ++ b' bằng cách nhóm vào các chuỗi giống hệt nhau. Tôi bỏ qua để giảm hình thức bình thường để làm cho ví dụ đơn giản hơn. – user21338

Trả lời

5

Các gói phần mềm có chứa một

instance Ring a => Group a where ... 

Các ví dụ đầu a trận đấu mỗi biểu hiện kiểu, vì vậy bất kỳ trường hợp với bất kỳ biểu hiện kiểu khác sẽ chồng chéo lên nhau. Chồng chéo đó chỉ gây ra lỗi nếu một cá thể như vậy thực sự được sử dụng ở đâu đó. Trong mô-đun của bạn, bạn sử dụng các ví dụ trong

instance Module Integer A where 
    r *> (A as) = A [(r <*> k,c) | (k,c) <- as] 

Lớp ModuleAbelianGroup hạn chế trên m parameter¹. Điều đó ngụ ý ràng buộc Group. Vì vậy, đối với trường hợp này, phiên bản Group của A phải được tra cứu. Trình biên dịch tìm thấy hai trường hợp phù hợp.

Đó là lỗi được báo cáo đầu tiên.

Tiếp theo là do trình biên dịch cố gắng tìm một phiên bản AbelianGroup cho A. Ví dụ duy nhất mà trình biên dịch biết về tại thời điểm đó là

instance (Group a, Ring a) => AbelianGroup a 

để cố gắng tìm kiếm instance Ring A where ..., nhưng tất nhiên không có.

Thay vì ý kiến ​​ra instance Group A where ..., bạn nên thêm một

instance AbelianGroup a 

(ngay cả khi đó là một lời nói dối, chúng tôi chỉ muốn làm cho nó biên dịch tại thời điểm này) và cũng thêm OverlappingInstances đến
{-# LANGUAGE #-} pragma .

Với OverlappingInstances, ví dụ đối sánh cụ thể nhất được chọn, do đó, nó thực hiện những gì bạn muốn ở đây.

¹ Nhân tiện, số A của bạn không phải là một phiên bản AbelianGroup và đúng là không thể trừ khi đơn đặt hàng không có liên quan trong danh sách [(Integer,String)].

+0

Bây giờ pragma của tôi cũng chứa 'OverlappingInstances'. Tôi đã thêm 'instance AbelianGroup A' vào cơ thể nhưng vẫn có' trường hợp chồng chéo cho nhóm A' và 'trường hợp chồng lấp cho AbelianGroup A' – user21338

+0

Phiên bản ghc nào? Một trường hợp tương tự biên dịch tại đây với ghc> = 7.2. Đối với ghc <= 7.0, mô-đun xác định 'Nhóm' và' AbelianGroup' cũng cần OverlappingInstances - nhưng điều đó có nghĩa là sửa đổi gói. –

+0

Nó là ghc 7.0.4 và có: Tôi đã thêm 'OverlappingInstances' vào' Group.hs' và bây giờ nó biên dịch như dự định. Cảm ơn rất nhiều! – user21338

2

Loại kiểm tra này không có tiện ích mở rộng ngôn ngữ đáng ghét.

{-# LANGUAGE MultiParamTypeClasses, TypeSynonymInstances #-} 
module A where 
import Algebra.Structures.Module 
import Algebra.Structures.CommutativeRing 
import Algebra.Structures.Group 

newtype A = A [(Integer,String)] 

instance Ring A where 
    A xs <+> A ys = A (xs ++ ys) 
    neg (A a) = A $ [((-k),c) | (k,c) <- a] 
    A x <*> A y = A [b | a <- x, b <- y ] 
    one = A [] 
    zero = A [] 

instance Module Integer A where 
    r *> (A as) = A [(r <*> k,c) | (k,c) <- as] 

Đó là một chút bối rối mà <+><*>neg được định nghĩa một cách độc lập trong RingGroup; chúng là các biểu tượng hoàn toàn riêng biệt, nhưng sau đó chúng được kết hợp với nhau trong trường hợp chung làm cho tất cả RingsGroups, vì vậy nếu Ring được xác định, không được xác định Group vì nó đã được nói đến. Tôi không chắc chắn điều này là bắt buộc đối với tác giả bằng cách hệ thống kiểu lớp hoạt động. Module yêu cầu Ring hoặc thay vì CommutativeRing. CommutativeRing về cơ bản đổi tên Ring; không có gì thêm nữa là phải được định nghĩa. Nó là nghĩa vụ phải cam kết bạn với những gì trong Haskell một khẳng định không thể kiểm soát của commutativity. Vì vậy, bạn có nghĩa vụ phải "chứng minh pháp luật CommutativeRing", do đó, để nói chuyện, bên ngoài mô-đun trước khi thực hiện các trường hợp Module. Tuy nhiên, lưu ý rằng các luật này được thể hiện trong các đề xuất kiểm tra nhanh, vì vậy bạn phải chạy nhanh trên propMulCommpropCommutativeRing dành riêng cho loại này.

Không biết phải làm gì với một và zero, nhưng bạn có thể vượt qua điểm về trật tự bằng cách sử dụng một cấu trúc phù hợp, có thể:

import qualified Data.Set as S 

newtype B = B {getBs :: S.Set (Integer,String) } 

Nhưng khi newtyped bạn cũng có thể, ví dụ, xác định lại Eq trên A để hiểu về nó, tôi cho là vậy. Trong thực tế, bạn phải chạy các đề xuất quickcheck.


Edit: Đây là một phiên bản với chất liệu bổ sung cần thiết cho QuickCheck http://hpaste.org/68351 cùng với "Không" và "OK" QuickCheck-báo cáo cho các trường hợp phương trình khác nhau. Gói này có vẻ khá hợp lý với tôi; Tôi nghĩ bạn nên xác định lại Mô-đun nếu bạn không muốn kinh doanh Ring và CommutativeRing, vì anh ấy nói "Chỉ xem xét trường hợp giao hoán, thay vào đó, có thể triển khai mô-đun trái và phải." Nếu không, bạn sẽ không thể sử dụng quickcheck, đó rõ ràng là điểm chính của gói, bây giờ tôi thấy những gì đang diễn ra, và điều mà anh ta đã làm cho nó cực kỳ dễ làm. Vì nó là A chính xác là thứ mà anh ta đang cố gắng loại trừ với việc sử dụng quickcheck toàn diện, điều này chắc chắn sẽ rất khó để đánh lừa trong trường hợp này.

+0

Tôi thích để lại '(<*>)' và 'một' là' undefined' vì tôi không có ý định 'A' để có cấu trúc vòng và theo cách này tôi sẽ gặp lỗi bất cứ khi nào cố gắng sử dụng nó. – user21338

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