Skip to content

Add blockST for nested ST scopes

GHC lacks the blockST and importVar primitives introduced by Launchbury/Sabry:

The two new combinators have these types:

blockST :: (forall r. ST (s,r) a) -> ST s a
importVar :: STRef s a -> STRef (s,r) a

They are useful, and have no runtime cost; I don't think it'd be hard to provide them. We need these primitives, I think:

promoteState# :: State# s -> State# (s,r) a
demoteState#  :: State# (s,r) -> State# s
promoteVar# :: MutVar# s a -> MutVar# (s,r) a

All three are implemented as no-ops. (Compare with newMutVar# etc in http://darcs.haskell.org/ghc/compiler/prelude/primops.txt.pp.)

Now the implementations look (something) like this. (For background see the current impementations of ST and STRef in http://darcs.haskell.org/packages/base/GHC (ST.lhs and STRef.lhs resp.)

blockST (ST thing) = ST (\s -> case thing (promoteState# s) of
                                 (s', r) -> (demoteState# s', r) )
promoteVar (STRef r) = STRef (promoteVar# r)

Things to think about:

  • Can we use coercions instead of primops? (I think yes for promote/demoteState but it's unsound to demote variables.)
  • I'm hazy about what type safety guarantees we still have in Core, where the representation of the state monad is exposed.
  • Nomenclature. I'm not attached to these particular names.
  • Is there other relevant background material?
Edited by Simon Peyton Jones
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information