2012-06-17 34 views
6

Một câu hỏi đơn giản, tôi hy vọng: Gói binary xác định hai loại, Get and Put. Trước đây về cơ bản là một đơn vị nhà nước, và sau này về cơ bản là một nhà văn. Cả tiểu bang và nhà văn đều có các trường hợp MonadFix hợp lý, vì vậy tôi mong đợi rằng GetPut cũng sẽ như vậy.Ví dụ MonadFix cho Đặt

Get. Put thì không. Vì vậy, có thể xác định một ví dụ thích hợp MonadFix cho Put (thực sự cho PutM)?

Một câu hỏi tổng quát hơn là: làm thế nào để người ta thường xác minh rằng một cá thể kiểu chữ thực sự đáp ứng các định luật của typeclass đó?

+5

Cách xác minh rằng kiểu chữ đáp ứng luật: ghi lại phương trình bạn đang cố xác minh, thay thế trong định nghĩa của hàm và đánh giá. Điều đó có dẫn đến hai thuật ngữ bình đẳng không? Nếu có, nó thỏa mãn luật pháp; nếu không, không. –

Trả lời

7

Như bạn có thể thấy trong nguồn cho gói nhị phân (Data.Binary.Put:71), cấu trúc dữ liệu được sử dụng cho các giá trị đơn nguyên là nghiêm ngặt trong trình tạo. Vì việc trích xuất giá trị từ đơn nguyên phải ép buộc cấu trúc mà trong đó giá trị được tìm thấy, điều này sẽ gây ra một vòng lặp vô hạn nếu trình tạo phụ thuộc vào đầu vào.

data PairS a = PairS a !Builder 
newtype PutM a = Put { unPut :: PairS a } 

Vì vậy, bạn có thể viết một ví dụ MonadFix, nhưng bạn sẽ không thể làm gì hữu ích với nó. Nhưng tôi không nghĩ rằng bạn có thể làm bất cứ điều gì hữu ích với MonadFix ở đây anyway, ít nhất là không có gì mà bạn không thể làm với đồng bằng cũ fix, kể từ khi đơn nguyên PutM là cơ bản Writer Builder (nhưng với một thực hiện chuyên ngành).

Đối với câu hỏi thứ hai, không liên quan đến câu hỏi đầu tiên, do đó bạn nên đặt câu hỏi đó làm câu hỏi riêng.

+0

Là một thử nghiệm, tôi chỉ viết ví dụ sau xuất hiện để làm việc: 'instance MonadFix PutM trong đó mfix f = let (a, b) = runPutM $ f a in (putLazyByteString b >> return a)'. Công việc này có nên không? Tôi có ngốc không? – mergeconflict

+0

Nếu bạn có thể chứng minh rằng nó tuân theo luật MonadFix, thì có vẻ như tôi sai về 'MonadFix' là không thể. Tuy nhiên, không có vấn đề gì khi triển khai nó, vì bạn chỉ có thể sử dụng 'fix' thông thường. –

1

Đây là câu trả lời cho câu hỏi thứ hai của bạn và theo dõi nhận xét của Daniel. Bạn xác minh luật bằng tay và tôi sẽ sử dụng các ví dụ về các Functor pháp luật về Maybe:

-- First law 
fmap id = id 

-- Proof 
fmap id 
= \x -> case x of 
    Nothing -> Nothing 
    Just a -> Just (id a) 
= \x -> case x of 
    Nothing -> Nothing 
    Just a -> Just a 
= \x -> case x of 
    Nothing -> x 
    Just a -> x 
= \x -> case x of 
    _ -> x 
= \x -> x 
= id 

-- Second law 
fmap f . fmap g = fmap (f . g) 

-- Proof 
fmap f . fmap g 
= \x -> fmap f (fmap g x) 
= \x -> fmap f (case x of 
    Nothing -> Nothing 
    Just a -> Just (f a)) 
= \x -> case x of 
    Nothing -> fmap f Nothing 
    Just a -> fmap f (Just (g a)) 
= \x -> case x of 
    Nothing -> Nothing 
    Just a -> Just (f (g a)) 
= \x -> case x of 
    Nothing -> Nothing 
    Just a -> Just ((f . g) a) 
= \x -> case x of 
    Nothing -> fmap (f . g) Nothing 
    Just a -> fmap (f . g) (Just a) 
= \x -> fmap (f . g) (case x of 
    Nothing -> Nothing 
    Just a -> Just a) 
= \x -> fmap (f . g) (case x of 
    Nothing -> x 
    Just a -> x) 
= \x -> fmap (f . g) (case x of 
    _ -> x) 
= \x -> fmap (f . g) x 
= fmap (f . g) 

Rõ ràng tôi có thể đã bỏ qua rất nhiều những bước nhưng tôi chỉ muốn nói ra bằng chứng đầy đủ. Trước hết, bạn sẽ gặp khó khăn trong việc đưa ra những loại luật này cho đến khi bạn có được chúng, vì vậy bạn nên bắt đầu từ từ và chậm và sau đó một khi bạn trở nên tốt hơn, bạn có thể bắt đầu kết hợp các bước và thậm chí làm một số trong đầu của bạn sau một thời gian để đơn giản hơn những người.

+0

Cảm ơn Gabriel. Có hai điều làm phức tạp các chứng minh này ... Một là đánh giá nghiêm ngặt so với lười biếng: bạn có thể viết một thể 'MonadFix' cho' Đặt' để thỏa mãn các đặc tính đại số của nó nhưng vẫn thất bại do đánh giá nghiêm ngặt. Và điều khác, có thể quan trọng hơn, là cuộc sống thực: bạn có thể viết ví dụ của bạn cho bất kỳ kiểu chữ nào đúng, và sau đó nó phá vỡ hoặc thoái lui bằng cách nào đó do thay đổi mã. Có vẻ như loại điều bạn có thể viết kiểm tra QuickCheck cho, nhưng tôi gặp khó khăn khi nhìn thấy làm thế nào để làm điều đó khi bạn đang cố gắng để kiểm tra máy biến áp monad ... – mergeconflict

+0

@mergeconflict Tôi đấu tranh với các vấn đề hồi quy tất cả các thời gian với 'ống của tôi 'thư viện.Bất cứ lúc nào tôi mở rộng thư viện, tôi phải chứng minh lại luật pháp cho các loại lớp học. Tôi có thể nói từ kinh nghiệm thực tế rằng những gì bạn kết thúc làm là "bao thanh toán" bằng chứng của bạn để bạn có thể tách ra các bộ phận thay đổi từ các bộ phận không. Về biến thế đơn nguyên, tôi xây dựng tất cả các mỏ trên [FreeT] (http://hackage.haskell.org/packages/archive/pipes/2.0.0/doc/html/Control-Monad-Trans-Free.html#t : FreeT), cung cấp một phiên bản MonadTrans miễn phí được đảm bảo là chính xác. –