{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE Rank2Types #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UnboxedTuples #-}
{-# LANGUAGE UndecidableInstances #-}
{-# OPTIONS_GHC -Wall #-}
module Control.Monad.ST2
(
ST(..), STRep
, fixST
, liftST
, runST
, STRef(..)
, newSTRef
, readSTRef
, writeSTRef
, type (∩)
, Common
, share
, liftL
, liftR
, use
, symm
, runST2
, toBaseST
, fromBaseST
, STret
, unsafeInterleaveST, unsafeDupableInterleaveST
, stToPrim
, unsafePrimToST
, unsafeSTToPrim
, unsafeInlineST
, stToIO
, ioToST
, RealWorld
) where
import Control.Applicative (Applicative(pure, (*>), (<*>), liftA2))
import Control.Exception.Base (catch, throwIO, NonTermination(..), BlockedIndefinitelyOnMVar(..))
import Control.Monad (Monad(return, (>>=), (>>)), ap, liftM2)
import Control.Monad.Primitive (PrimMonad(primitive, PrimState), PrimBase(internal), primToPrim, unsafePrimToPrim, unsafeInlinePrim)
import qualified Control.Monad.ST as BaseST
import Data.Eq (Eq((==)))
import Data.Function (($), (.))
import Data.Functor (Functor(fmap))
import Data.Kind (Type)
#if !(MIN_VERSION_base(4,11,0))
import Data.Monoid (Monoid(mempty, mappend))
#else
import Data.Monoid (Monoid(mempty))
#endif
import Data.Semigroup (Semigroup((<>)))
import GHC.IO (IO(IO),unsafeDupableInterleaveIO)
import GHC.MVar (readMVar, putMVar, newEmptyMVar)
import GHC.Exts (State#, unsafeCoerce#, MutVar#, newMutVar#, readMutVar#, writeMutVar#, sameMutVar#, RealWorld, noDuplicate#, RuntimeRep, TYPE, Any, isTrue#)
import GHC.Show (Show(showsPrec, showList), showString, showList__)
import Theory.Named (type (~~))
import Unsafe.Coerce (unsafeCoerce)
import qualified GHC.Exts as GHCExts
toBaseST :: ST s a -> BaseST.ST s a
{-# INLINE toBaseST #-}
toBaseST :: ST s a -> ST s a
toBaseST = ST s a -> ST s a
forall a b. a -> b
unsafeCoerce
fromBaseST :: BaseST.ST s a -> ST s a
{-# INLINE fromBaseST #-}
fromBaseST :: ST s a -> ST s a
fromBaseST = ST s a -> ST s a
forall a b. a -> b
unsafeCoerce
newtype ST (s :: Type) a = ST (STRep (Any ~~ s) a)
type STRep s a = State# s -> (# State# s, a #)
instance PrimMonad (ST s) where
type PrimState (ST s) = s
primitive :: (State# (PrimState (ST s)) -> (# State# (PrimState (ST s)), a #))
-> ST s a
primitive = STRep (Any ~~ s) a -> ST s a
forall s a. STRep (Any ~~ s) a -> ST s a
ST (STRep (Any ~~ s) a -> ST s a)
-> ((State# s -> (# State# s, a #)) -> STRep (Any ~~ s) a)
-> (State# s -> (# State# s, a #))
-> ST s a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (State# s -> (# State# s, a #)) -> STRep (Any ~~ s) a
forall s a. (State# s -> (# State# s, a #)) -> STRep (Any ~~ s) a
repToAny#
{-# INLINE primitive #-}
instance PrimBase (ST s) where
internal :: ST s a
-> State# (PrimState (ST s)) -> (# State# (PrimState (ST s)), a #)
internal (ST STRep (Any ~~ s) a
p) = STRep (Any ~~ s) a -> State# s -> (# State# s, a #)
forall s a. STRep (Any ~~ s) a -> State# s -> (# State# s, a #)
repFromAny# STRep (Any ~~ s) a
p
{-# INLINE internal #-}
data STret s a = STret (State# s) a
liftST :: ST s a -> State# s -> STret s a
liftST :: ST s a -> State# s -> STret s a
liftST (ST STRep (Any ~~ s) a
m) = \State# s
s -> case STRep (Any ~~ s) a
m (State# s -> State# (Any ~~ s)
unsafeCoerce# State# s
s) of (# State# (Any ~~ s)
s', a
r #) -> State# s -> a -> STret s a
forall s a. State# s -> a -> STret s a
STret (State# (Any ~~ s) -> State# s
unsafeCoerce# State# (Any ~~ s)
s') a
r
noDuplicateST :: ST s ()
{-# INLINE noDuplicateST #-}
noDuplicateST :: ST s ()
noDuplicateST = STRep (Any ~~ s) () -> ST s ()
forall s a. STRep (Any ~~ s) a -> ST s a
ST (STRep (Any ~~ s) () -> ST s ()) -> STRep (Any ~~ s) () -> ST s ()
forall a b. (a -> b) -> a -> b
$ \State# (Any ~~ s)
s -> (# State# (Any ~~ s) -> State# (Any ~~ s)
forall d. State# d -> State# d
noDuplicate# State# (Any ~~ s)
s, () #)
{-# INLINE unsafeInterleaveST #-}
unsafeInterleaveST :: ST s a -> ST s a
unsafeInterleaveST :: ST s a -> ST s a
unsafeInterleaveST ST s a
m = ST s a -> ST s a
forall s a. ST s a -> ST s a
unsafeDupableInterleaveST (ST s ()
forall s. ST s ()
noDuplicateST ST s () -> ST s a -> ST s a
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ST s a
m)
{-# NOINLINE unsafeDupableInterleaveST #-}
unsafeDupableInterleaveST :: ST s a -> ST s a
unsafeDupableInterleaveST :: ST s a -> ST s a
unsafeDupableInterleaveST (ST STRep (Any ~~ s) a
m) = STRep (Any ~~ s) a -> ST s a
forall s a. STRep (Any ~~ s) a -> ST s a
ST ( \ State# (Any ~~ s)
s ->
let
r :: a
r = case STRep (Any ~~ s) a
m State# (Any ~~ s)
s of (# State# (Any ~~ s)
_, a
res #) -> a
res
in
(# State# (Any ~~ s)
s, a
r #)
)
stToIO :: ST RealWorld a -> IO a
stToIO :: ST RealWorld a -> IO a
stToIO (ST STRep (Any ~~ RealWorld) a
m) = (State# RealWorld -> (# State# RealWorld, a #)) -> IO a
forall a. (State# RealWorld -> (# State# RealWorld, a #)) -> IO a
IO (STRep (Any ~~ RealWorld) a
-> State# RealWorld -> (# State# RealWorld, a #)
forall a b. a -> b
unsafeCoerce STRep (Any ~~ RealWorld) a
m)
ioToST :: IO a -> ST RealWorld a
ioToST :: IO a -> ST RealWorld a
ioToST (IO State# RealWorld -> (# State# RealWorld, a #)
m) = STRep (Any ~~ RealWorld) a -> ST RealWorld a
forall s a. STRep (Any ~~ s) a -> ST s a
ST ((State# RealWorld -> (# State# RealWorld, a #))
-> STRep (Any ~~ RealWorld) a
forall a b. a -> b
unsafeCoerce State# RealWorld -> (# State# RealWorld, a #)
m)
unsafeIOToST :: IO a -> ST s a
unsafeIOToST :: IO a -> ST s a
unsafeIOToST (IO State# RealWorld -> (# State# RealWorld, a #)
io) = STRep (Any ~~ s) a -> ST s a
forall s a. STRep (Any ~~ s) a -> ST s a
ST (STRep (Any ~~ s) a -> ST s a) -> STRep (Any ~~ s) a -> ST s a
forall a b. (a -> b) -> a -> b
$ \ State# (Any ~~ s)
s -> ((State# RealWorld -> (# State# RealWorld, a #))
-> STRep (Any ~~ s) a
unsafeCoerce# State# RealWorld -> (# State# RealWorld, a #)
io) State# (Any ~~ s)
s
unsafeSTToIO :: ST s a -> IO a
unsafeSTToIO :: ST s a -> IO a
unsafeSTToIO (ST STRep (Any ~~ s) a
m) = (State# RealWorld -> (# State# RealWorld, a #)) -> IO a
forall a. (State# RealWorld -> (# State# RealWorld, a #)) -> IO a
IO (STRep (Any ~~ s) a -> State# RealWorld -> (# State# RealWorld, a #)
unsafeCoerce# STRep (Any ~~ s) a
m)
stToPrim :: PrimMonad m => ST (PrimState m) a -> m a
{-# INLINE stToPrim #-}
stToPrim :: ST (PrimState m) a -> m a
stToPrim = ST (PrimState m) a -> m a
forall (m1 :: * -> *) (m2 :: * -> *) a.
(PrimBase m1, PrimMonad m2, PrimState m1 ~ PrimState m2) =>
m1 a -> m2 a
primToPrim
unsafePrimToST :: PrimBase m => m a -> ST s a
{-# INLINE unsafePrimToST #-}
unsafePrimToST :: m a -> ST s a
unsafePrimToST = m a -> ST s a
forall (m1 :: * -> *) (m2 :: * -> *) a.
(PrimBase m1, PrimMonad m2) =>
m1 a -> m2 a
unsafePrimToPrim
unsafeSTToPrim :: PrimBase m => ST s a -> m a
{-# INLINE unsafeSTToPrim #-}
unsafeSTToPrim :: ST s a -> m a
unsafeSTToPrim = ST s a -> m a
forall (m1 :: * -> *) (m2 :: * -> *) a.
(PrimBase m1, PrimMonad m2) =>
m1 a -> m2 a
unsafePrimToPrim
unsafeInlineST :: ST s a -> a
{-# INLINE unsafeInlineST #-}
unsafeInlineST :: ST s a -> a
unsafeInlineST = ST s a -> a
forall (m :: * -> *) a. PrimBase m => m a -> a
unsafeInlinePrim
data STRef s a = STRef (MutVar# s a)
newSTRef :: a -> ST s (STRef s a)
newSTRef :: a -> ST s (STRef s a)
newSTRef a
init = STRep (Any ~~ s) (STRef s a) -> ST s (STRef s a)
forall s a. STRep (Any ~~ s) a -> ST s a
ST (STRep (Any ~~ s) (STRef s a) -> ST s (STRef s a))
-> STRep (Any ~~ s) (STRef s a) -> ST s (STRef s a)
forall a b. (a -> b) -> a -> b
$ \State# (Any ~~ s)
s1# ->
case a -> State# s -> (# State# s, MutVar# s a #)
forall k1 d. k1 -> State# d -> (# State# d, MutVar# d k1 #)
newMutVar# a
init (State# (Any ~~ s) -> State# s
forall k (s :: k) s'. State# (Any ~~ s) -> State# s'
rwFromAny# State# (Any ~~ s)
s1#) of { (# State# s
s2#, MutVar# s a
var# #) ->
(# (State# s -> State# (Any ~~ s)
unsafeCoerce# State# s
s2#), MutVar# s a -> STRef s a
forall s a. MutVar# s a -> STRef s a
STRef MutVar# s a
var# #) }
readSTRef :: STRef s a -> ST s a
readSTRef :: STRef s a -> ST s a
readSTRef (STRef MutVar# s a
var#) = STRep (Any ~~ s) a -> ST s a
forall s a. STRep (Any ~~ s) a -> ST s a
ST (STRep (Any ~~ s) a -> ST s a) -> STRep (Any ~~ s) a -> ST s a
forall a b. (a -> b) -> a -> b
$ \State# (Any ~~ s)
s1# -> (# State# s, a #) -> (# State# (Any ~~ s), a #)
forall s a. (# State# s, a #) -> (# State# (Any ~~ s), a #)
rwTupleToAny# (MutVar# s a -> State# s -> (# State# s, a #)
forall d k1. MutVar# d k1 -> State# d -> (# State# d, k1 #)
readMutVar# MutVar# s a
var# (State# (Any ~~ s) -> State# s
forall k (s :: k) s'. State# (Any ~~ s) -> State# s'
rwFromAny# State# (Any ~~ s)
s1#))
writeSTRef :: STRef s a -> a -> ST s ()
writeSTRef :: STRef s a -> a -> ST s ()
writeSTRef (STRef MutVar# s a
var#) a
val = STRep (Any ~~ s) () -> ST s ()
forall s a. STRep (Any ~~ s) a -> ST s a
ST (STRep (Any ~~ s) () -> ST s ()) -> STRep (Any ~~ s) () -> ST s ()
forall a b. (a -> b) -> a -> b
$ \State# (Any ~~ s)
s1# ->
case MutVar# s a -> a -> State# s -> State# s
forall d k1. MutVar# d k1 -> k1 -> State# d -> State# d
writeMutVar# MutVar# s a
var# a
val (State# (Any ~~ s) -> State# s
forall k (s :: k) s'. State# (Any ~~ s) -> State# s'
rwFromAny# State# (Any ~~ s)
s1#) of
State# s
s2# -> (# (State# s -> State# (Any ~~ s)
forall k (s :: k) s'. State# s' -> State# (Any ~~ s)
rwToAny# State# s
s2#), () #)
instance Eq (STRef s a) where
STRef MutVar# s a
v1# == :: STRef s a -> STRef s a -> Bool
== STRef MutVar# s a
v2# = Int# -> Bool
isTrue# (MutVar# s a -> MutVar# s a -> Int#
forall d k1. MutVar# d k1 -> MutVar# d k1 -> Int#
sameMutVar# MutVar# s a
v1# MutVar# s a
v2#)
instance Functor (ST s) where
fmap :: (a -> b) -> ST s a -> ST s b
fmap a -> b
f (ST STRep (Any ~~ s) a
m) = STRep (Any ~~ s) b -> ST s b
forall s a. STRep (Any ~~ s) a -> ST s a
ST (STRep (Any ~~ s) b -> ST s b) -> STRep (Any ~~ s) b -> ST s b
forall a b. (a -> b) -> a -> b
$ \ State# (Any ~~ s)
s ->
case (STRep (Any ~~ s) a
m State# (Any ~~ s)
s) of { (# State# (Any ~~ s)
new_s, a
r #) ->
(# State# (Any ~~ s)
new_s, a -> b
f a
r #) }
instance Applicative (ST s) where
{-# INLINE pure #-}
{-# INLINE (*>) #-}
pure :: a -> ST s a
pure a
x = STRep (Any ~~ s) a -> ST s a
forall s a. STRep (Any ~~ s) a -> ST s a
ST (\ State# (Any ~~ s)
s -> (# State# (Any ~~ s)
s, a
x #))
ST s a
m *> :: ST s a -> ST s b -> ST s b
*> ST s b
k = ST s a
m ST s a -> (a -> ST s b) -> ST s b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \ a
_ -> ST s b
k
<*> :: ST s (a -> b) -> ST s a -> ST s b
(<*>) = ST s (a -> b) -> ST s a -> ST s b
forall (m :: * -> *) a b. Monad m => m (a -> b) -> m a -> m b
ap
liftA2 :: (a -> b -> c) -> ST s a -> ST s b -> ST s c
liftA2 = (a -> b -> c) -> ST s a -> ST s b -> ST s c
forall (m :: * -> *) a1 a2 r.
Monad m =>
(a1 -> a2 -> r) -> m a1 -> m a2 -> m r
liftM2
instance Monad (ST s) where
{-# INLINE (>>=) #-}
>> :: ST s a -> ST s b -> ST s b
(>>) = ST s a -> ST s b -> ST s b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
(*>)
(ST STRep (Any ~~ s) a
m) >>= :: ST s a -> (a -> ST s b) -> ST s b
>>= a -> ST s b
k
= STRep (Any ~~ s) b -> ST s b
forall s a. STRep (Any ~~ s) a -> ST s a
ST (\ State# (Any ~~ s)
s ->
case (STRep (Any ~~ s) a
m State# (Any ~~ s)
s) of { (# State# (Any ~~ s)
new_s, a
r #) ->
case (a -> ST s b
k a
r) of { ST STRep (Any ~~ s) b
k2 ->
(STRep (Any ~~ s) b
k2 State# (Any ~~ s)
new_s) }})
instance Semigroup a => Semigroup (ST s a) where
<> :: ST s a -> ST s a -> ST s a
(<>) = (a -> a -> a) -> ST s a -> ST s a -> ST s a
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 a -> a -> a
forall a. Semigroup a => a -> a -> a
(<>)
instance Monoid a => Monoid (ST s a) where
mempty :: ST s a
mempty = a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure a
forall a. Monoid a => a
mempty
#if !(MIN_VERSION_base(4,11,0))
mappend = liftA2 mappend
#endif
instance Show (ST s a) where
showsPrec :: Int -> ST s a -> ShowS
showsPrec Int
_ ST s a
_ = String -> ShowS
showString String
"<<ST action>>"
showList :: [ST s a] -> ShowS
showList = (ST s a -> ShowS) -> [ST s a] -> ShowS
forall a. (a -> ShowS) -> [a] -> ShowS
showList__ (Int -> ST s a -> ShowS
forall a. Show a => Int -> a -> ShowS
showsPrec Int
0)
type s ∩ s' = Common s s'
data Common s s'
share :: STRef s a -> ST s (STRef (Common s s') a)
{-# INLINE share #-}
share :: STRef s a -> ST s (STRef (Common s s') a)
share = STRef (Common s s') a -> ST s (STRef (Common s s') a)
forall (m :: * -> *) a. Monad m => a -> m a
return (STRef (Common s s') a -> ST s (STRef (Common s s') a))
-> (STRef s a -> STRef (Common s s') a)
-> STRef s a
-> ST s (STRef (Common s s') a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. STRef s a -> STRef (Common s s') a
forall a b. a -> b
unsafeCoerce
liftL :: ST s a -> ST (Common s s') a
{-# INLINE liftL #-}
liftL :: ST s a -> ST (Common s s') a
liftL = ST s a -> ST (Common s s') a
forall a b. a -> b
unsafeCoerce
liftR :: ST s' a -> ST (Common s s') a
{-# INLINE liftR #-}
liftR :: ST s' a -> ST (Common s s') a
liftR = ST s' a -> ST (Common s s') a
forall a b. a -> b
unsafeCoerce
use :: STRef (Common s s') a -> STRef s a
{-# INLINE use #-}
use :: STRef (Common s s') a -> STRef s a
use = STRef (Common s s') a -> STRef s a
forall a b. a -> b
unsafeCoerce
symm :: STRef (Common s s') a -> STRef (Common s' s) a
{-# INLINE symm #-}
symm :: STRef (Common s s') a -> STRef (Common s' s) a
symm = STRef (Common s s') a -> STRef (Common s' s) a
forall a b. a -> b
unsafeCoerce
runST2 :: (forall s s'. ST (Common s s') a) -> a
{-# INLINE runST2 #-}
runST2 :: (forall (s :: k) (s' :: k). ST (Common s s') a) -> a
runST2 (ST st_rep) = case (State# (Any ~~ Common Any Any)
-> (# State# (Any ~~ Common Any Any), a #))
-> (# State# (Any ~~ Common Any Any), a #)
forall k o (s :: k). (State# (Any ~~ s) -> o) -> o
runRegion# State# (Any ~~ Common Any Any)
-> (# State# (Any ~~ Common Any Any), a #)
st_rep of (# State# (Any ~~ Common Any Any)
_, a
a #) -> a
a
runST :: (forall s. ST s a) -> a
{-# INLINE runST #-}
runST :: (forall s. ST s a) -> a
runST (ST st_rep) = case (State# (Any ~~ Any) -> (# State# (Any ~~ Any), a #))
-> (# State# (Any ~~ Any), a #)
forall k o (s :: k). (State# (Any ~~ s) -> o) -> o
runRegion# State# (Any ~~ Any) -> (# State# (Any ~~ Any), a #)
st_rep of (# State# (Any ~~ Any)
_, a
a #) -> a
a
fixST :: (a -> ST s a) -> ST s a
fixST :: (a -> ST s a) -> ST s a
fixST a -> ST s a
k = IO a -> ST s a
forall a s. IO a -> ST s a
unsafeIOToST (IO a -> ST s a) -> IO a -> ST s a
forall a b. (a -> b) -> a -> b
$ do
MVar a
m <- IO (MVar a)
forall a. IO (MVar a)
newEmptyMVar
a
ans <- IO a -> IO a
forall a. IO a -> IO a
unsafeDupableInterleaveIO
(MVar a -> IO a
forall a. MVar a -> IO a
readMVar MVar a
m IO a -> (BlockedIndefinitelyOnMVar -> IO a) -> IO a
forall e a. Exception e => IO a -> (e -> IO a) -> IO a
`catch` \BlockedIndefinitelyOnMVar
BlockedIndefinitelyOnMVar ->
NonTermination -> IO a
forall e a. Exception e => e -> IO a
throwIO NonTermination
NonTermination)
a
result <- ST s a -> IO a
forall s a. ST s a -> IO a
unsafeSTToIO (a -> ST s a
k a
ans)
MVar a -> a -> IO ()
forall a. MVar a -> a -> IO ()
putMVar MVar a
m a
result
a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return a
result
runRegion# :: forall (r :: RuntimeRep) (o :: TYPE r) s.
(State# (Any ~~ s) -> o) -> o
runRegion# :: (State# (Any ~~ s) -> o) -> o
runRegion# State# (Any ~~ s) -> o
m = (State# RealWorld -> o) -> o
forall o. (State# RealWorld -> o) -> o
GHCExts.runRW# ((State# (Any ~~ s) -> o) -> State# RealWorld -> o
unsafeCoerce# State# (Any ~~ s) -> o
m)
{-# INLINE runRegion# #-}
rwToAny# :: forall s s'. State# s' -> State# (Any ~~ s)
rwToAny# :: State# s' -> State# (Any ~~ s)
rwToAny# State# s'
x# = State# s' -> State# (Any ~~ s)
unsafeCoerce# State# s'
x#
{-# INLINE rwToAny# #-}
rwFromAny# :: forall s s'. State# (Any ~~ s) -> State# s'
rwFromAny# :: State# (Any ~~ s) -> State# s'
rwFromAny# State# (Any ~~ s)
x# = State# (Any ~~ s) -> State# s'
unsafeCoerce# State# (Any ~~ s)
x#
{-# INLINE rwFromAny# #-}
rwTupleToAny# :: forall s a. (# State# s, a #) -> (# State# (Any ~~ s), a #)
rwTupleToAny# :: (# State# s, a #) -> (# State# (Any ~~ s), a #)
rwTupleToAny# (# State# s
x, a
a #) = (# State# s -> State# (Any ~~ s)
unsafeCoerce# State# s
x, a
a #)
{-# INLINE rwTupleToAny# #-}
repToAny# :: (State# s -> (# State# s, a #)) -> STRep (Any ~~ s) a
repToAny# :: (State# s -> (# State# s, a #)) -> STRep (Any ~~ s) a
repToAny# = (State# s -> (# State# s, a #)) -> STRep (Any ~~ s) a
unsafeCoerce#
{-# INLINE repToAny# #-}
repFromAny# :: STRep (Any ~~ s) a -> (State# s -> (# State# s, a #))
repFromAny# :: STRep (Any ~~ s) a -> State# s -> (# State# s, a #)
repFromAny# = STRep (Any ~~ s) a -> State# s -> (# State# s, a #)
unsafeCoerce#
{-# INLINE repFromAny# #-}