2011-11-04 47 views
7

我寫了下面的功能:GHC由於無法統一類型​​變量而拒絕ST monad代碼?

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

但是當我試圖編譯我得到了以下錯誤:

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 

誰能幫助?

回答

12

這與預期完全相同。 STRef僅在runST的一次運行中有效。並且您嘗試將外部STRef納入runST的新運行。這是無效的。這將允許純代碼中的任意副作用。

所以,你嘗試的是不可能實現的。按設計!

7

你需要留在ST範圍內:

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

(正如哈馬爾指出,使用>=您需要的Ord類型類,其Num不提供。)

+1

注意,這仍然不會進行類型檢查,因爲約束應該是'Ord',而不是'Num'。 – hammar

+0

感謝您的發現。 – dave4420

相關問題