这种runST的推广是否安全?

时间:2014-07-13 15:25:54

标签: haskell state-monad

Control.Monad.ST包中的

base包含runST来运行严格的状态变换器monad:

runST :: (forall s. ST s a) -> a

但是,我需要runST的广义版本:

runSTCont :: (forall s . (forall b . ST s b -> b) -> a) -> a
runSTCont f = f $ \m -> runST $ unsafeCoerce m

我的问题是:unsafeCoerse使用安全吗? (我想是的,因为据我了解,索引s的唯一目的是防止s - 在结果a中泄露runSTCont - 索引值。{{1}的类型}不能泄漏s - 索引值,所以它应该没问题。)

请注意,runST可以用runSTCont表示,因此runSTCont至少与runST一样通用:

runST' :: (forall s. ST s a) -> a 
runST' m = runSTCont $ \runST -> runST m

1 个答案:

答案 0 :(得分:12)

我不这么认为:

crash = runSTCont crasher where
  crasher :: forall s. (forall b . ST s b -> b) -> Integer
  crasher go =
    let r :: forall a. STRef s (a -> a)
        r = go $ newSTRef id
    in go $ do writeSTRef r (tail . tail)
               f <- readSTRef r
               return $ f (17 :: Integer)

问题在于Haskell缺乏价值限制。