Add internal, primToIO and primToST
[darcs-mirrors/primitive.git] / Control / Monad / Primitive.hs
1 {-# LANGUAGE MagicHash, UnboxedTuples, TypeFamilies #-}
2
3 -- |
4 -- Module : Control.Monad.Primitive
5 -- Copyright : (c) Roman Leshchinskiy 2009
6 -- License : BSD-style
7 --
8 -- Maintainer : Roman Leshchinskiy <rl@cse.unsw.edu.au>
9 -- Portability : non-portable
10 --
11 -- Primitive state-transformer monads
12 --
13
14 module Control.Monad.Primitive (
15 PrimMonad(..), RealWorld, primitive_, primToIO, primToST
16 ) where
17
18 import GHC.Prim ( State#, RealWorld )
19 import GHC.IOBase ( IO(..) )
20 import GHC.ST ( ST(..) )
21
22 -- | Class of primitive state-transformer monads
23 class Monad m => PrimMonad m where
24 -- | State token type
25 type PrimState m
26
27 -- | Execute a primitive operation
28 primitive :: (State# (PrimState m) -> (# State# (PrimState m), a #)) -> m a
29
30
31 -- | Expose the internal structure of the monad
32 internal :: m a -> State# (PrimState m) -> (# State# (PrimState m), a #)
33
34 -- | Execute a primitive operation with no result
35 primitive_ :: PrimMonad m
36 => (State# (PrimState m) -> State# (PrimState m)) -> m ()
37 {-# INLINE primitive_ #-}
38 primitive_ f = primitive (\s# -> (# f s#, () #))
39
40 instance PrimMonad IO where
41 type PrimState IO = RealWorld
42 primitive = IO
43 internal (IO p) = p
44
45 instance PrimMonad (ST s) where
46 type PrimState (ST s) = s
47 primitive = ST
48 internal (ST p) = p
49
50 -- | Convert a 'PrimMonad' with a 'RealWorld' state token to 'IO'
51 primToIO :: (PrimMonad m, PrimState m ~ RealWorld) => m a -> IO a
52 primToIO p = IO (internal p)
53
54 -- | Convert a 'PrimMonad' to 'ST'
55 primToST :: PrimMonad m => m a -> ST (PrimState m) a
56 primToST p = ST (internal p)
57