STM - a basic Monad, consider that atomicallythat now STM a -> IO ashould look like, if we have STMT.
. , , :
write :: Int -> RandT StdGen STM [Int]
write n = do
-- random list of indexes, so you don't need to interleave random and stm code at all
rn <- getRandomRs (0, numTVars)
lift $ go rn
where go [] = return []
go (i:is) = do tvars <- tvars -- this is redundant, could be taken out of the loop
temp <- readArray tvars i
writeArray tvars i (temp + 1)
rands <- go is
return $ i : rands
RandT StateT lift:
instance MonadTrans (StateT s) where
lift m = StateT $ \ s -> do
a <- m
return (a, s)
, :
do x <- lift baseAction1
y <- lift baseAction2
return $ f x y
do x <- StateT $ \s -> do { a <- baseAction1; return (a, s) }
y <- StateT $ \s -> do { a <- baseAction2; return (a, s) }
return $ f x y
StateT (\s -> do { a <- baseAction1; return (a, s) }) >>= \ x ->
StateT (\s -> do { a <- baseAction2; return (a, s) }) >>= \ y ->
return $ f x y
>>=
StateT $ \s -> do
~(a, s') <- runStateT (StateT (\s -> do { a <- baseAction1; return (a, s) })) s
runStateT ((\ x -> StateT (\s -> do { a <- baseAction2; return (a, s) }) >>= \ y -> return $ f x y) a) s'
StateT runStateT :
StateT $ \s -> do
~(x, s') <- do { a <- baseAction1; return (a, s) }))
runStateT ((\ x -> StateT (\s -> do { a <- baseAction2; return (a, s) }) >>= \ y -> return $ f x y) x) s'
inlining/reduction:
StateT $ \s -> do
~(x, s') <- do { a <- baseAction1; return (a, s) }))
~(y, s'') <- do { a <- baseAction2; return (a, s') }))
return (f x y, s'')
, GHC , , ( , , ):
StateT $ \s -> do
x <- baseAction1
y <- baseAction2
return (f x y, s)
lift do x <- baseAction1
y <- baseAction2
return $ f x y