Add blockST for nested ST scopes
GHC lacks the
importVar primitives introduced by Launchbury/Sabry:
- http://www.cs.indiana.edu/\~sabry/papers/monadic-state-ax.pdf (section 10).
- See also Fluet & Morrisset http://www.cs.rit.edu/\~mtf/research/rgn-monad/JFP06/jfp06.pdf (page 7ff)
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
STRef in http://darcs.haskell.org/packages/base/GHC (
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/demoteStatebut 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?