7

我写了以下函数:

(.>=.) :: 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

任何人都可以帮忙吗?

4

2 回答 2

12

这完全符合预期。AnSTRef仅在一次运行中有效runST。并且您尝试将外部STRef放入新的runST. 那是无效的。这将允许纯代码中的任意副作用。

所以,你尝试的东西是不可能实现的。按设计!

于 2011-11-04T09:23:25.143 回答
7

您需要留在ST上下文中:

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

(正如 hammar 指出的那样,要使用>=你需要typeclass Ord,它Num不提供。)

于 2011-11-04T10:02:42.700 回答