2011-12-03 24 views
9

Có lý do chính đáng nào khiến chức năng check trong thư viện Contol.Concurent.STM có loại Bool -> STM a và trả về undefined về thành công chứ không phải loại Bool -> STM()? Cách nó được thực hiện kiểm tra loại sẽ chính thức biên dịch một khối làm kết thúc với check foo chỉ để thất bại trong thời gian chạy với *** Exception: Prelude.undefined.Chức năng kiểm tra Haskell STM trả về không xác định

+0

Đây là một câu hỏi hay; nó có vẻ như 'kiểm tra' được mô tả trong [giấy bất biến STM] (http://research.microsoft.com/en-us/um/people/simonpj/papers/stm/stm-invariants.pdf) giờ đây được gọi là' alwaysSucceeds'. Nó không rõ ràng với tôi những gì hiện tại 'kiểm tra' nào. – acfoltzer

+0

Vâng, tôi không biết mục đích của nó như thế nào. Kinda tò mò bây giờ. –

+0

'kiểm tra b = nếu b sau đó trở về undefined khác retry' tôi yêu cầu nó nên đọc' kiểm tra b = nếu b sau đó trở về() khác retry' –

Trả lời

5

Có vẻ như đó là định nghĩa trình giữ chỗ cho GHC PrimOp, như "định nghĩa" seq _ y = y được thay thế bởi trình biên dịch bằng mã thực thi nguyên thủy thực tế. Các PrimOp implementation of check mất một biểu thức và thêm nó vào một danh sách toàn cầu của bất biến như mô tả trong STM invariants paper.

Dưới đây là một ví dụ siêu giả tạo sửa đổi từ giấy để phù hợp với kiểu mới của check:

import Control.Concurrent.STM 

data LimitedTVar = LTVar { tvar :: TVar Int 
         , limit :: Int 
         } 

newLimitedTVar :: Int -> STM LimitedTVar 
newLimitedTVar lim = do 
    tv <- newTVar 0 
    return $ LTVar tv lim 

incrLimitedTVar :: LimitedTVar -> STM() 
incrLimitedTVar (LTVar tv lim) = do 
    val <- readTVar $ tv 
    let val' = val + 1 
    check (val' <= lim) 
    writeTVar tv val' 

test :: STM() 
test = do 
    ltv <- newLimitedTVar 2 
    incrLimitedTVar ltv -- should work 
    incrLimitedTVar ltv -- should work still 
    incrLimitedTVar ltv -- should fail; we broke the invariant 

Thực tế, điều này sẽ có ích để khẳng định bất biến về trạng thái chia sẻ nơi không những khẳng định có thể là một dấu hiệu của sự mâu thuẫn tạm thời. Sau đó bạn có thể muốn thử lại với kỳ vọng về sự bất biến đó trở thành sự thật một lần nữa, nhưng kể từ khi ví dụ này kéo dài vĩnh viễn phá vỡ bất biến, nó chỉ gọi retry mãi mãi và xuất hiện để treo. Kiểm tra bài báo để biết các ví dụ tốt hơn nhiều, nhưng hãy nhớ rằng loại đã thay đổi kể từ khi xuất bản.

+0

Tôi hiểu cách kiểm tra hoạt động. Tôi không hiểu tại sao nó được viết theo cách như vậy mà 'kiểm tra True >> = writeTVar t' sẽ vượt qua kiểm tra loại, nhưng gây ra một lỗi thời gian chạy. Tôi khẳng định rằng mã trên sẽ không kiểm tra kiểu trừ khi 't' là loại vô dụng' TVar() '. –

+0

Ahhh, tôi nghĩ câu hỏi đó là nhiều hơn theo hướng, "nếu đây là tất cả các mã, điểm là gì?" Tôi đồng ý rằng nó có vẻ như loại nên được 'Bool -> STM()'. – acfoltzer

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