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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With