{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
module Orc
(
Orc
, runOrc
, collect
, par
, (<|>)
, stop
, signal
, (<+>)
, (<?>)
, cut
, val
, eagerly
, putStrLine
, echo
, onlyUntil
, butAfter
, notBefore
, delay
, publish
, repeating
, sync
, takeOrc
, dropOrc
, zipOrc
, liftList
, syncList
, runChan
, printOrc
, prompt
, (#)
, shift
, reset
)
where
import HIO (HIO, runHIO, newGroup, local, finished, close)
import LCPS (CPS(..), (#), shift, reset)
import Control.Monad (guard, join, MonadPlus(..))
import Control.Concurrent.MonadIO
( MonadIO(..)
, Chan(..)
, MVar(..)
, putMVar
, takeMVar
, newEmptyMVar
, readMVar
, fork
, threadDelay
, newMVar
, tryTakeMVar
, tryPutMVar
, writeChan )
import Control.Applicative ((<|>))
import Control.DeepSeq (NFData(..), deepseq)
import Control.Concurrent.STM.MonadIO
( readTVarSTM
, writeTVarSTM
, modifyTVar
, atomically
, readTVar
, newTVar )
import qualified Control.Concurrent.StdInOut as S
import System.IO.Unsafe (unsafePerformIO)
type Orc = CPS () HIO
runOrc :: Orc a -> IO ()
runOrc :: forall a. Orc a -> IO ()
runOrc Orc a
p = forall b. HIO b -> IO ()
runHIO (Orc a
p forall {k} (result :: k) (m :: k -> *) answer.
CPS result m answer -> (answer -> m result) -> m result
# \a
_ -> forall (m :: * -> *) a. Monad m => a -> m a
return ())
stop :: Orc a
stop :: forall a. Orc a
stop = forall {k} answer (m :: k -> *) (result :: k).
((answer -> m result) -> m result) -> CPS result m answer
CPS forall a b. (a -> b) -> a -> b
$ \a -> HIO ()
_ -> forall (m :: * -> *) a. Monad m => a -> m a
return ()
signal :: Orc ()
signal :: Orc ()
signal = forall (m :: * -> *) a. Monad m => a -> m a
return ()
par :: Orc a -> Orc a -> Orc a
par :: forall a. Orc a -> Orc a -> Orc a
par = forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
(<|>)
eagerly :: Orc a -> Orc (Orc a)
eagerly :: forall a. Orc a -> Orc (Orc a)
eagerly Orc a
p = forall {k} answer (m :: k -> *) (result :: k).
((answer -> m result) -> m result) -> CPS result m answer
CPS forall a b. (a -> b) -> a -> b
$ \Orc a -> HIO ()
k -> do
MVar a
res <- forall (io :: * -> *) a. MonadIO io => io (MVar a)
newEmptyMVar
Group
w <- HIO Group
newGroup
ThreadId
threadId <- forall (io :: * -> *). HasFork io => io () -> io ThreadId
fork forall a b. (a -> b) -> a -> b
$ Orc a
p forall {m :: * -> *} {a}.
MonadIO m =>
CPS () m a -> (MVar a, Group) -> m ()
`saveOnce` (MVar a
res, Group
w)
ThreadId
_ <- forall a. Group -> HIO a -> HIO a
local Group
w forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. Monad m => a -> m a
return ThreadId
threadId
Orc a -> HIO ()
k (forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall (io :: * -> *) a. MonadIO io => MVar a -> io a
readMVar MVar a
res)
cut :: Orc a -> Orc a
cut :: forall a. Orc a -> Orc a
cut = forall (m :: * -> *) a. Monad m => m (m a) -> m a
join forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Orc a -> Orc (Orc a)
eagerly
putStrLine :: String -> Orc ()
putStrLine :: String -> Orc ()
putStrLine String
str = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall (io :: * -> *). MonadIO io => String -> io ()
S.putStrLine String
str
printOrc :: Show a => Orc a -> IO ()
printOrc :: forall a. Show a => Orc a -> IO ()
printOrc Orc a
p = forall a. IO a -> IO a
S.setupStdInOut forall a b. (a -> b) -> a -> b
$ forall a. Orc a -> IO ()
runOrc forall a b. (a -> b) -> a -> b
$ do
a
a <- Orc a
p
String -> Orc ()
putStrLine (String
"Ans = " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show a
a)
(<+>) :: Orc a -> Orc a -> Orc a
Orc a
p <+> :: forall a. Orc a -> Orc a -> Orc a
<+> Orc a
q = forall {k} answer (m :: k -> *) (result :: k).
((answer -> m result) -> m result) -> CPS result m answer
CPS forall a b. (a -> b) -> a -> b
$ \a -> HIO ()
k -> do
Group
w <- HIO Group
newGroup
ThreadId
threadId <- forall (io :: * -> *). HasFork io => io () -> io ThreadId
fork (Orc a
p forall {k} (result :: k) (m :: k -> *) answer.
CPS result m answer -> (answer -> m result) -> m result
# a -> HIO ()
k)
ThreadId
_ <- forall a. Group -> HIO a -> HIO a
local Group
w forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. Monad m => a -> m a
return ThreadId
threadId
Group -> HIO ()
finished Group
w
Orc a
q forall {k} (result :: k) (m :: k -> *) answer.
CPS result m answer -> (answer -> m result) -> m result
# a -> HIO ()
k
(<?>) :: Orc a -> Orc a -> Orc a
Orc a
p <?> :: forall a. Orc a -> Orc a -> Orc a
<?> Orc a
q = do
MVar ()
tripwire <- forall (io :: * -> *) a. MonadIO io => io (MVar a)
newEmptyMVar
do a
x <- Orc a
p
Bool
_ <- forall (io :: * -> *) a. MonadIO io => MVar a -> a -> io Bool
tryPutMVar MVar ()
tripwire ()
forall (m :: * -> *) a. Monad m => a -> m a
return a
x
forall a. Orc a -> Orc a -> Orc a
<+>
do Maybe ()
triggered <- forall (io :: * -> *) a. MonadIO io => MVar a -> io (Maybe a)
tryTakeMVar MVar ()
tripwire
case Maybe ()
triggered of
Maybe ()
Nothing -> Orc a
q
Just ()
_ -> forall a. Orc a
stop
CPS () m a
p saveOnce :: CPS () m a -> (MVar a, Group) -> m ()
`saveOnce` (MVar a
r,Group
w) = do
MVar ()
ticket <- forall (io :: * -> *) a. MonadIO io => a -> io (MVar a)
newMVar ()
CPS () m a
p forall {k} (result :: k) (m :: k -> *) answer.
CPS result m answer -> (answer -> m result) -> m result
# \a
x -> forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ (forall (io :: * -> *) a. MonadIO io => MVar a -> io a
takeMVar MVar ()
ticket forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (io :: * -> *) a. MonadIO io => MVar a -> a -> io ()
putMVar MVar a
r a
x forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Group -> IO ()
close Group
w)
echo :: Int -> MVar (Maybe a) -> MVar () -> Orc a
echo :: forall a. Int -> MVar (Maybe a) -> MVar () -> Orc a
echo Int
0 MVar (Maybe a)
_ MVar ()
end = forall a b. Orc a -> Orc b
silent (forall (io :: * -> *) a. MonadIO io => MVar a -> a -> io ()
putMVar MVar ()
end ())
echo Int
j MVar (Maybe a)
vals MVar ()
end = do
Maybe a
mx <- forall (io :: * -> *) a. MonadIO io => MVar a -> io a
takeMVar MVar (Maybe a)
vals
case Maybe a
mx of
Maybe a
Nothing -> forall a b. Orc a -> Orc b
silent (forall (io :: * -> *) a. MonadIO io => MVar a -> a -> io ()
putMVar MVar ()
end ())
Just a
x -> forall (m :: * -> *) a. Monad m => a -> m a
return a
x forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall a. Int -> MVar (Maybe a) -> MVar () -> Orc a
echo (Int
jforall a. Num a => a -> a -> a
-Int
1) MVar (Maybe a)
vals MVar ()
end
silent :: Orc a -> Orc b
silent :: forall a b. Orc a -> Orc b
silent Orc a
p = Orc a
p forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall a. Orc a
stop
onlyUntil :: Orc a -> Orc b -> Orc b
Orc a
p onlyUntil :: forall a b. Orc a -> Orc b -> Orc b
`onlyUntil` Orc b
done = forall a. Orc a -> Orc a
cut (forall a b. Orc a -> Orc b
silent Orc a
p forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Orc b
done)
butAfter :: (RealFrac n, Show n) => Orc a -> (n, Orc a) -> Orc a
Orc a
p butAfter :: forall n a. (RealFrac n, Show n) => Orc a -> (n, Orc a) -> Orc a
`butAfter` (n
t,Orc a
def) = forall a. Orc a -> Orc a
cut (Orc a
p forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (forall a. (RealFrac a, Show a) => a -> Orc ()
delay n
t forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Orc a
def))
notBefore :: Orc a -> Float -> Orc a
Orc a
p notBefore :: forall a. Orc a -> Float -> Orc a
`notBefore` Float
w = forall a b c. (a -> b -> c) -> Orc a -> Orc b -> Orc c
sync forall a b. a -> b -> a
const Orc a
p (forall a. (RealFrac a, Show a) => a -> Orc ()
delay Float
w)
delay :: (RealFrac a, Show a) => a -> Orc ()
delay :: forall a. (RealFrac a, Show a) => a -> Orc ()
delay a
w = (forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall (io :: * -> *). HasFork io => Int -> io ()
threadDelay (forall a b. (RealFrac a, Integral b) => a -> b
round (a
w forall a. Num a => a -> a -> a
* a
1000000)))
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (forall a b. Orc a -> Orc b
silent forall a b. (a -> b) -> a -> b
$ do
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (a
w forall a. Ord a => a -> a -> Bool
> a
100)
String -> Orc ()
putStrLine (String
"Just checking you meant to wait " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show a
w forall a. [a] -> [a] -> [a]
++ String
" seconds"))
sync :: (a -> b -> c) -> Orc a -> Orc b -> Orc c
sync :: forall a b c. (a -> b -> c) -> Orc a -> Orc b -> Orc c
sync a -> b -> c
f Orc a
p Orc b
q = do
Orc a
po <- forall a. Orc a -> Orc (Orc a)
eagerly Orc a
p
Orc b
qo <- forall a. Orc a -> Orc (Orc a)
eagerly Orc b
q
forall (f :: * -> *) a. Applicative f => a -> f a
pure a -> b -> c
f forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Orc a
po forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Orc b
qo
val :: Orc a -> Orc a
val :: forall a. Orc a -> Orc a
val Orc a
p = forall {k} answer (m :: k -> *) (result :: k).
((answer -> m result) -> m result) -> CPS result m answer
CPS forall a b. (a -> b) -> a -> b
$ \a -> HIO ()
k -> do
MVar a
res <- forall (io :: * -> *) a. MonadIO io => io (MVar a)
newEmptyMVar
Group
w <- HIO Group
newGroup
ThreadId
threadId <- forall (io :: * -> *). HasFork io => io () -> io ThreadId
fork forall a b. (a -> b) -> a -> b
$ Orc a
p forall {m :: * -> *} {a}.
MonadIO m =>
CPS () m a -> (MVar a, Group) -> m ()
`saveOnce` (MVar a
res, Group
w)
ThreadId
_ <- forall a. Group -> HIO a -> HIO a
local Group
w forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. Monad m => a -> m a
return ThreadId
threadId
a -> HIO ()
k (forall a. IO a -> a
unsafePerformIO forall a b. (a -> b) -> a -> b
$ forall (io :: * -> *) a. MonadIO io => MVar a -> io a
readMVar MVar a
res)
prompt :: String -> Orc String
prompt :: String -> Orc String
prompt String
str = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall (io :: * -> *). HasFork io => String -> io String
S.prompt String
str
publish :: NFData a => a -> Orc a
publish :: forall a. NFData a => a -> Orc a
publish a
x = forall a b. NFData a => a -> b -> b
deepseq a
x forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. Monad m => a -> m a
return a
x
repeating :: Orc a -> Orc a
repeating :: forall a. Orc a -> Orc a
repeating Orc a
p = do
a
x <- Orc a
p
forall (m :: * -> *) a. Monad m => a -> m a
return a
x forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall a. Orc a -> Orc a
repeating Orc a
p
sandbox :: Orc a -> MVar (Maybe a) -> MVar () -> Orc ()
sandbox :: forall a. Orc a -> MVar (Maybe a) -> MVar () -> Orc ()
sandbox Orc a
p MVar (Maybe a)
vals MVar ()
end =
((Orc a
p forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (forall (io :: * -> *) a. MonadIO io => MVar a -> a -> io ()
putMVar MVar (Maybe a)
vals forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. a -> Maybe a
Just)) forall a. Orc a -> Orc a -> Orc a
<+> forall (io :: * -> *) a. MonadIO io => MVar a -> a -> io ()
putMVar MVar (Maybe a)
vals forall a. Maybe a
Nothing)
forall a b. Orc a -> Orc b -> Orc b
`onlyUntil` forall (io :: * -> *) a. MonadIO io => MVar a -> io a
takeMVar MVar ()
end
takeOrc :: Int -> Orc a -> Orc a
takeOrc :: forall a. Int -> Orc a -> Orc a
takeOrc Int
n Orc a
p = do
MVar (Maybe a)
vals <- forall (io :: * -> *) a. MonadIO io => io (MVar a)
newEmptyMVar
MVar ()
end <- forall (io :: * -> *) a. MonadIO io => io (MVar a)
newEmptyMVar
forall a. Int -> MVar (Maybe a) -> MVar () -> Orc a
echo Int
n MVar (Maybe a)
vals MVar ()
end forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall a b. Orc a -> Orc b
silent (forall a. Orc a -> MVar (Maybe a) -> MVar () -> Orc ()
sandbox Orc a
p MVar (Maybe a)
vals MVar ()
end)
dropOrc :: Int -> Orc a -> Orc a
dropOrc :: forall a. Int -> Orc a -> Orc a
dropOrc Int
n Orc a
p = do
TVar Int
countdown <- forall (io :: * -> *) a. MonadIO io => a -> io (TVar a)
newTVar Int
n
a
x <- Orc a
p
forall (m :: * -> *) a. Monad m => m (m a) -> m a
join forall a b. (a -> b) -> a -> b
$ forall (io :: * -> *) a. MonadIO io => STM a -> io a
atomically forall a b. (a -> b) -> a -> b
$ do
Int
w <- forall a. TVar a -> STM a
readTVarSTM TVar Int
countdown
if Int
w forall a. Eq a => a -> a -> Bool
== Int
0
then forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. Monad m => a -> m a
return a
x
else do
forall a. TVar a -> a -> STM ()
writeTVarSTM TVar Int
countdown (Int
wforall a. Num a => a -> a -> a
-Int
1)
forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Orc a
stop
zipOrc :: Orc a -> Orc b -> Orc (a, b)
zipOrc :: forall a b. Orc a -> Orc b -> Orc (a, b)
zipOrc Orc a
p Orc b
q = do
MVar (Maybe a)
pvals <- forall (io :: * -> *) a. MonadIO io => io (MVar a)
newEmptyMVar
MVar (Maybe b)
qvals <- forall (io :: * -> *) a. MonadIO io => io (MVar a)
newEmptyMVar
MVar ()
end <- forall (io :: * -> *) a. MonadIO io => io (MVar a)
newEmptyMVar
forall a b.
MVar (Maybe a) -> MVar (Maybe b) -> MVar () -> Orc (a, b)
zipp MVar (Maybe a)
pvals MVar (Maybe b)
qvals MVar ()
end
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall a b. Orc a -> Orc b
silent (forall a. Orc a -> MVar (Maybe a) -> MVar () -> Orc ()
sandbox Orc a
p MVar (Maybe a)
pvals MVar ()
end)
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall a b. Orc a -> Orc b
silent (forall a. Orc a -> MVar (Maybe a) -> MVar () -> Orc ()
sandbox Orc b
q MVar (Maybe b)
qvals MVar ()
end)
zipp :: MVar (Maybe a) -> MVar (Maybe b) -> MVar () -> Orc (a, b)
zipp :: forall a b.
MVar (Maybe a) -> MVar (Maybe b) -> MVar () -> Orc (a, b)
zipp MVar (Maybe a)
pvals MVar (Maybe b)
qvals MVar ()
end = do
Maybe a
mx <- forall (io :: * -> *) a. MonadIO io => MVar a -> io a
takeMVar MVar (Maybe a)
pvals
Maybe b
my <- forall (io :: * -> *) a. MonadIO io => MVar a -> io a
takeMVar MVar (Maybe b)
qvals
case Maybe a
mx of
Maybe a
Nothing -> forall a b. Orc a -> Orc b
silent (forall (io :: * -> *) a. MonadIO io => MVar a -> a -> io ()
putMVar MVar ()
end () forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (io :: * -> *) a. MonadIO io => MVar a -> a -> io ()
putMVar MVar ()
end ())
Just a
x -> case Maybe b
my of
Maybe b
Nothing -> forall a b. Orc a -> Orc b
silent (forall (io :: * -> *) a. MonadIO io => MVar a -> a -> io ()
putMVar MVar ()
end () forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (io :: * -> *) a. MonadIO io => MVar a -> a -> io ()
putMVar MVar ()
end ())
Just b
y -> forall (m :: * -> *) a. Monad m => a -> m a
return (a
x, b
y) forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall a b.
MVar (Maybe a) -> MVar (Maybe b) -> MVar () -> Orc (a, b)
zipp MVar (Maybe a)
pvals MVar (Maybe b)
qvals MVar ()
end
collect :: Orc a -> Orc [a]
collect :: forall a. Orc a -> Orc [a]
collect Orc a
p = do
TVar [a]
accum <- forall (io :: * -> *) a. MonadIO io => a -> io (TVar a)
newTVar []
forall a b. Orc a -> Orc b
silent (Orc a
p forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \a
v -> forall (io :: * -> *) a.
MonadIO io =>
TVar a -> (a -> a) -> io (a, a)
modifyTVar TVar [a]
accum (a
vforall a. a -> [a] -> [a]
:)) forall a. Orc a -> Orc a -> Orc a
<+> forall (io :: * -> *) a. MonadIO io => TVar a -> io a
readTVar TVar [a]
accum
runChan :: Chan a -> Orc a -> IO ()
runChan :: forall a. Chan a -> Orc a -> IO ()
runChan Chan a
ch Orc a
p = forall a. Orc a -> IO ()
runOrc forall a b. (a -> b) -> a -> b
$ (Orc a
p forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall (io :: * -> *) a. MonadIO io => Chan a -> a -> io ()
writeChan Chan a
ch)
syncList :: [Orc a] -> CPS () HIO [a]
syncList :: forall a. [Orc a] -> CPS () HIO [a]
syncList [Orc a]
ps = forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
sequence (forall a b. (a -> b) -> [a] -> [b]
map forall a. Orc a -> Orc (Orc a)
eagerly [Orc a]
ps) forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
sequence
scan :: (a -> s -> s) -> s -> Orc a -> Orc s
scan :: forall a s. (a -> s -> s) -> s -> Orc a -> Orc s
scan a -> s -> s
f s
s Orc a
p = do
TVar s
accum <- forall (io :: * -> *) a. MonadIO io => a -> io (TVar a)
newTVar s
s
a
x <- Orc a
p
(s
_w, s
w') <- forall (io :: * -> *) a.
MonadIO io =>
TVar a -> (a -> a) -> io (a, a)
modifyTVar TVar s
accum (a -> s -> s
f a
x)
forall (m :: * -> *) a. Monad m => a -> m a
return s
w'
liftList :: (MonadPlus list) => [a] -> list a
liftList :: forall (list :: * -> *) a. MonadPlus list => [a] -> list a
liftList [a]
ps = forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr forall (m :: * -> *) a. MonadPlus m => m a -> m a -> m a
mplus forall (m :: * -> *) a. MonadPlus m => m a
mzero forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map forall (m :: * -> *) a. Monad m => a -> m a
return [a]
ps