Add internal, primToIO and primToST
authorRoman Leshchinskiy <rl@cse.unsw.edu.au>
Fri, 4 Dec 2009 07:38:24 +0000 (07:38 +0000)
committerRoman Leshchinskiy <rl@cse.unsw.edu.au>
Fri, 4 Dec 2009 07:38:24 +0000 (07:38 +0000)
Control/Monad/Primitive.hs

index c9a10f9..44b247e 100644 (file)
@@ -11,7 +11,9 @@
 -- Primitive state-transformer monads
 --
 
-module Control.Monad.Primitive ( PrimMonad(..), RealWorld, primitive_ ) where
+module Control.Monad.Primitive (
+  PrimMonad(..), RealWorld, primitive_, primToIO, primToST
+) where
 
 import GHC.Prim   ( State#, RealWorld )
 import GHC.IOBase ( IO(..) )
@@ -25,6 +27,10 @@ class Monad m => PrimMonad m where
   -- | Execute a primitive operation
   primitive :: (State# (PrimState m) -> (# State# (PrimState m), a #)) -> m a
 
+
+  -- | Expose the internal structure of the monad
+  internal :: m a -> State# (PrimState m) -> (# State# (PrimState m), a #)
+
 -- | Execute a primitive operation with no result
 primitive_ :: PrimMonad m
               => (State# (PrimState m) -> State# (PrimState m)) -> m ()
@@ -34,8 +40,18 @@ primitive_ f = primitive (\s# -> (# f s#, () #))
 instance PrimMonad IO where
   type PrimState IO = RealWorld
   primitive = IO
+  internal (IO p) = p
 
 instance PrimMonad (ST s) where
   type PrimState (ST s) = s
   primitive = ST
+  internal (ST p) = p
+
+-- | Convert a 'PrimMonad' with a 'RealWorld' state token to 'IO'
+primToIO :: (PrimMonad m, PrimState m ~ RealWorld) => m a -> IO a
+primToIO p = IO (internal p)
+
+-- | Convert a 'PrimMonad' to 'ST'
+primToST :: PrimMonad m => m a -> ST (PrimState m) a
+primToST p = ST (internal p)