9a174383f8826ae1ef16dd11f4551700fd8356da
[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 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.
96 liftST :: ST s a -> State# s -> STret s a
97 liftST (ST m) = \s -> case m s of (# s', r #) -> STret s' r
98
99 noDuplicateST :: ST s ()
100 noDuplicateST = ST $ \s -> (# noDuplicate# s, () #)
101
102 -- | 'unsafeInterleaveST' allows an 'ST' computation to be deferred
103 -- lazily. When passed a value of type @ST a@, the 'ST' computation will
104 -- only be performed when the value of the @a@ is demanded.
105 {-# INLINE unsafeInterleaveST #-}
106 unsafeInterleaveST :: ST s a -> ST s a
107 unsafeInterleaveST m = unsafeDupableInterleaveST (noDuplicateST >> m)
108
109 -- | 'unsafeDupableInterleaveST' allows an 'ST' computation to be deferred
110 -- lazily. When passed a value of type @ST a@, the 'ST' computation will
111 -- only be performed when the value of the @a@ is demanded.
112 --
113 -- The computation may be performed multiple times by different threads,
114 -- possibly at the same time. To prevent this, use 'unsafeInterleaveST' instead.
115 --
116 -- @since 4.11
117 {-# NOINLINE unsafeDupableInterleaveST #-}
118 -- See Note [unsafeDupableInterleaveIO should not be inlined]
119 -- in GHC.IO.Unsafe
120 unsafeDupableInterleaveST :: ST s a -> ST s a
121 unsafeDupableInterleaveST (ST m) = ST ( \ s ->
122 let
123 r = case m s of (# _, res #) -> res
124 in
125 (# s, r #)
126 )
127
128 -- | @since 2.01
129 instance Show (ST s a) where
130 showsPrec _ _ = showString "<<ST action>>"
131 showList = showList__ (showsPrec 0)
132
133 {-# INLINE runST #-}
134 -- | Return the value computed by a state transformer computation.
135 -- The @forall@ ensures that the internal state used by the 'ST'
136 -- computation is inaccessible to the rest of the program.
137 runST :: (forall s. ST s a) -> a
138 runST (ST st_rep) = case runRW# st_rep of (# _, a #) -> a
139 -- See Note [Definition of runRW#] in GHC.Magic