e9d79d9220343c267e3bf3c0470cb156edfafae4
[ghc.git] / libraries / base / GHC / ST.hs
1 {-# LANGUAGE Unsafe #-}
2 {-# LANGUAGE NoImplicitPrelude, MagicHash, UnboxedTuples, RankNTypes #-}
3 {-# OPTIONS_HADDOCK hide #-}
4
5 -----------------------------------------------------------------------------
6 -- |
7 -- Module : GHC.ST
8 -- Copyright : (c) The University of Glasgow, 1992-2002
9 -- License : see libraries/base/LICENSE
10 --
11 -- Maintainer : cvs-ghc@haskell.org
12 -- Stability : internal
13 -- Portability : non-portable (GHC Extensions)
14 --
15 -- The 'ST' Monad.
16 --
17 -----------------------------------------------------------------------------
18
19 module GHC.ST (
20 ST(..), STret(..), STRep,
21 fixST, runST,
22
23 -- * Unsafe functions
24 liftST, unsafeInterleaveST, unsafeDupableInterleaveST
25 ) where
26
27 import GHC.Base
28 import GHC.Show
29 import qualified Control.Monad.Fail as Fail
30
31 default ()
32
33 -- The state-transformer monad proper. By default the monad is strict;
34 -- too many people got bitten by space leaks when it was lazy.
35
36 -- | The strict state-transformer monad.
37 -- A computation of type @'ST' s a@ transforms an internal state indexed
38 -- by @s@, and returns a value of type @a@.
39 -- The @s@ parameter is either
40 --
41 -- * an uninstantiated type variable (inside invocations of 'runST'), or
42 --
43 -- * 'RealWorld' (inside invocations of 'Control.Monad.ST.stToIO').
44 --
45 -- It serves to keep the internal states of different invocations
46 -- of 'runST' separate from each other and from invocations of
47 -- 'Control.Monad.ST.stToIO'.
48 --
49 -- The '>>=' and '>>' operations are strict in the state (though not in
50 -- values stored in the state). For example,
51 --
52 -- @'runST' (writeSTRef _|_ v >>= f) = _|_@
53 newtype ST s a = ST (STRep s a)
54 type STRep s a = State# s -> (# State# s, a #)
55
56 -- | @since 2.01
57 instance Functor (ST s) where
58 fmap f (ST m) = ST $ \ s ->
59 case (m s) of { (# new_s, r #) ->
60 (# new_s, f r #) }
61
62 -- | @since 4.4.0.0
63 instance Applicative (ST s) where
64 {-# INLINE pure #-}
65 {-# INLINE (*>) #-}
66 pure x = ST (\ s -> (# s, x #))
67 m *> k = m >>= \ _ -> k
68 (<*>) = ap
69 liftA2 = liftM2
70
71 -- | @since 2.01
72 instance Monad (ST s) where
73 {-# INLINE (>>=) #-}
74 (>>) = (*>)
75 (ST m) >>= k
76 = ST (\ s ->
77 case (m s) of { (# new_s, r #) ->
78 case (k r) of { ST k2 ->
79 (k2 new_s) }})
80
81 -- | @since 4.11.0.0
82 instance Fail.MonadFail (ST s) where
83 fail s = errorWithoutStackTrace s
84
85 -- | @since 4.11.0.0
86 instance Semigroup a => Semigroup (ST s a) where
87 (<>) = liftA2 (<>)
88
89 -- | @since 4.11.0.0
90 instance Monoid a => Monoid (ST s a) where
91 mempty = pure mempty
92
93 data STret s a = STret (State# s) a
94
95 -- liftST is useful when we want a lifted result from an ST computation. See
96 -- fixST below.
97 liftST :: ST s a -> State# s -> STret s a
98 liftST (ST m) = \s -> case m s of (# s', r #) -> STret s' r
99
100 noDuplicateST :: ST s ()
101 noDuplicateST = ST $ \s -> (# noDuplicate# s, () #)
102
103 -- | 'unsafeInterleaveST' allows an 'ST' computation to be deferred
104 -- lazily. When passed a value of type @ST a@, the 'ST' computation will
105 -- only be performed when the value of the @a@ is demanded.
106 {-# INLINE unsafeInterleaveST #-}
107 unsafeInterleaveST :: ST s a -> ST s a
108 unsafeInterleaveST m = unsafeDupableInterleaveST (noDuplicateST >> m)
109
110 -- | 'unsafeDupableInterleaveST' allows an 'ST' computation to be deferred
111 -- lazily. When passed a value of type @ST a@, the 'ST' computation will
112 -- only be performed when the value of the @a@ is demanded.
113 --
114 -- The computation may be performed multiple times by different threads,
115 -- possibly at the same time. To prevent this, use 'unsafeInterleaveST' instead.
116 --
117 -- @since 4.11
118 {-# NOINLINE unsafeDupableInterleaveST #-}
119 -- See Note [unsafeDupableInterleaveIO should not be inlined]
120 -- in GHC.IO.Unsafe
121 unsafeDupableInterleaveST :: ST s a -> ST s a
122 unsafeDupableInterleaveST (ST m) = ST ( \ s ->
123 let
124 r = case m s of (# _, res #) -> res
125 in
126 (# s, r #)
127 )
128
129 -- | Allow the result of a state transformer computation to be used (lazily)
130 -- inside the computation.
131 -- Note that if @f@ is strict, @'fixST' f = _|_@.
132 fixST :: (a -> ST s a) -> ST s a
133 fixST k = ST $ \ s ->
134 let ans = liftST (k r) s
135 STret _ r = ans
136 in
137 case ans of STret s' x -> (# s', x #)
138
139 -- | @since 2.01
140 instance Show (ST s a) where
141 showsPrec _ _ = showString "<<ST action>>"
142 showList = showList__ (showsPrec 0)
143
144 {-# INLINE runST #-}
145 -- | Return the value computed by a state transformer computation.
146 -- The @forall@ ensures that the internal state used by the 'ST'
147 -- computation is inaccessible to the rest of the program.
148 runST :: (forall s. ST s a) -> a
149 runST (ST st_rep) = case runRW# st_rep of (# _, a #) -> a
150 -- See Note [Definition of runRW#] in GHC.Magic