Is this generalization of runST safe?

haskell, state-monad

Solution

I don't think so:

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)

The problem is that Haskell lacks the value restriction.

Problem

`Control.Monad.ST` in the `base` package contains `runST` to run the strict state-transformer monad: ``` runST :: (forall s. ST s a) -> a ``` However, I need a generalized version of `runST`: ``` runSTCont :: (forall s . (forall b . ST s b -> b) -> a) -> a runSTCont f = f $ \m -> runST $ unsafeCoerce m ``` My question is: Is this use of `unsafeCoerse` safe? (I guess so, because as I understand, the only purpose of the index `s` is to prevent to leak `s`-indexed values in the result `a`. The type of `runSTCont` cannot leak `s`-indexed values so it should be OK.) Note that `runST` can be expressed in terms of `runSTCont` so `runSTCont` is at least as general as `runST`: ``` runST' :: (forall s. ST s a) -> a runST' m = runSTCont $ \runST -> runST m ```

Original source