{-# LANGUAGE NoMonomorphismRestriction, FlexibleContexts, ScopedTypeVariables, BangPatterns #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeApplications #-}
module Main where
import Control.Monad.IO.Class
import Control.Monad
import Control.Effects.Signal
import Control.Effects.State
import Control.Effects.Parallel
import Control.Effects.Early
import Control.Effects.Async
import Control.Effects.List
import Control.Effects.Yield
import Control.Effects.Resource
import Control.Concurrent hiding (yield)
import System.IO
import Data.Function
-- Should infer
ex1 = signal True
-- Should compile
ex2 :: MonadEffect (Throw Bool) m => m ()
ex2 = throwSignal False
ex3 = do
void $ discardAllExceptions ex1
void $ showAllExceptions ex2
handleException (\(_ :: Bool) -> return ()) ex2
handleSignal (\(_ :: Bool) -> Resume 5) ex1
-- Nested Early
testEarly1 :: Monad m => m Bool
testEarly1 = handleEarly $ do
return ()
_ <- earlyReturn True
_ <- handleEarly $ do
return ()
earlyReturn (123 :: Int)
_ <- testEarly2
return True
testEarly2 :: Monad m => m Char
testEarly2 = handleEarly $
earlyReturn 'a'
orderTest :: (MonadEffects '[HandleException Bool, Throw Bool, State Int] m, MonadIO m) => m ()
orderTest = do
setState (1 :: Int)
_ :: Either Bool () <- handleToEitherRecursive $ do
setState (2 :: Int)
void $ throwSignal True
setState (3 :: Int)
st :: Int <- getState
liftIO (print st)
inc :: Int -> Int
inc !x = x + 1
task :: (MonadEffect (State Int) m) => m Int
task = do
replicateM_ 10000000 (modifyState inc)
st <- getState
st `seq` return st
main :: IO ()
main = do
orderTest & handleException (\(_ :: Bool) -> return ())
& implementStateViaStateT (0 :: Int)
orderTest & implementStateViaStateT (0 :: Int)
& handleException (\(_ :: Bool) -> return ())
putStrLn "Starting sequential test"
replicateM_ 8 (implementStateViaStateT (0 :: Int) task >>= print)
putStrLn "Sequential test done"
putStrLn "Starting parallel test"
implementStateViaStateT (0 :: Int) $ do
res <- parallelWithSequence (replicate 8 task)
mapM_ (liftIO . print) res
putStrLn "Parallel test done"
parallelTest ::
(MonadEffects '[Async, NonDeterminism] m, MonadIO m) => m (AsyncThread m (Int, Char))
parallelTest = do
n <- choose [1,2,3,4]
async $ do
liftIO $ threadDelay ((5 - n) * 1000000)
l <- choose "ab"
return (n, l)
mainAsync :: IO ()
mainAsync = do
threads <- evaluateToList parallelTest
forM_ threads $ \thread ->
evaluateToList (do
p <- waitAsync thread
liftIO $ print p
)
yieldTest ::
(MonadEffects '[Yield Int, Async] m, MonadIO m) => m ()
yieldTest = do
yield @Int 5
t <- async $ do
liftIO $ putStrLn "yielding 6"
yield @Int 6
liftIO $ putStrLn "yielding 10"
yield @Int 10
t2 <- async $ do
liftIO $ putStrLn "yielding 8"
yield @Int 8
liftIO $ putStrLn "yielding 9"
yield @Int 9
yield @Int 7
waitAsync t
waitAsync t2
return ()
mainYield :: IO ()
mainYield = do
hSetBuffering stdout LineBuffering
await <- implementYieldViaMVar @Int yieldTest
traverseYielded_ await $ \res -> do
print res
void getLine
testResource = evaluateAll $ bracket
(choose [True, False] >>= \tf -> liftIO (putStrLn ("acq " ++ show tf)) >> return tf)
(\tf _ -> liftIO $ putStrLn ("cleaning " ++ show tf))
(\tf -> if tf then liftIO $ putStrLn "true" else error "io err" >> liftIO (putStrLn "false") )