Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is this generalization of runST safe?

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
like image 327
Péter Diviánszky Avatar asked Jul 13 '14 15:07

Péter Diviánszky


1 Answers

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.

like image 195
Philip JF Avatar answered Nov 17 '22 06:11

Philip JF