2011-11-04 14 views
7

tôi đã viết các chức năng sau:GHC từ chối mã mon đơn ST vì không thể thống nhất các biến kiểu?

(.>=.) :: Num a => STRef s a -> a -> Bool 
r .>=. x = runST $ do 
v <- readSTRef r 
return $ v >= x 

nhưng khi tôi đã cố gắng để biên dịch tôi đã nhận lỗi sau:

Could not deduce (s ~ s1) 
from the context (Num a) 
    bound by the type signature for 
      .>=. :: Num a => STRef s a -> a -> Bool 
    at test.hs:(27,1)-(29,16) 
    `s' is a rigid type variable bound by 
     the type signature for .>=. :: Num a => STRef s a -> a -> Bool 
     at test.hs:27:1 
    `s1' is a rigid type variable bound by 
     a type expected by the context: ST s1 Bool at test.hs:27:12 
Expected type: STRef s1 a 
    Actual type: STRef s a 
In the first argument of `readSTRef', namely `r' 
In a stmt of a 'do' expression: v <- readSTRef r 

bất cứ ai có thể giúp đỡ?

Trả lời

12

Điều này đúng như dự định. An STRef chỉ hợp lệ trong một lần chạy là runST. Và bạn cố gắng đặt một bên ngoài STRef vào một hoạt động mới của runST. Điều đó không hợp lệ. Điều đó sẽ cho phép các tác dụng phụ tùy ý trong mã thuần túy.

Vì vậy, những gì bạn cố gắng không thể đạt được. Thiết kế bởi!

7

Bạn cần phải ở lại trong bối cảnh ST:

(.>=.) :: Ord a => STRef s a -> a -> ST s Bool 
r .>=. x = do 
v <- readSTRef r 
return $ v >= x 

(Và như Hammar chỉ ra, để sử dụng >= bạn cần Ord typeclass, mà Num không cung cấp.)

+1

Lưu ý rằng điều này vẫn sẽ không đánh dấu kiểm tra, vì ràng buộc phải là 'Ord', không phải là' Num'. – hammar

+0

Cảm ơn vì đã phát hiện ra điều đó. – dave4420