2011-11-04 11 views
7

Aşağıdaki fonksiyon yazdım:GHC, ST monad kodunu tür değişkenlerini birleştiremedi mi?

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

ama derlemeye çalıştığımda aşağıdaki hata var:

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 

Herkes yardımcı olabilir?

cevap

12

Bu, tam olarak amaçlandığı gibidir. Bir STRef sadece bir seferde runST geçerlidir. Ve STRef harici bir runST yeni bir koşuya koymaya çalışın. Bu geçerli değil. Bu, saf kodda keyfi yan etkilere izin verir.

Yani, denediğiniz şeyi başarmak imkansız. Tasarım gereği!

7

Sen ST kapsamında kalmak gerekir:

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

(Ve hammar işaret ettiği gibi, sen sağlamaz NumOrd typeclass, ihtiyaç >= kullanmak.)

+1

Not bu o Kısıtlama, hala "Num'" değil, "Ord" olmalıdır. – hammar

+0

Bunu tespit ettiğiniz için teşekkürler. – dave4420