{-# 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.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) -> return $ 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 <- parallelMapM id (replicate 8 task) mapM_ (liftIO . print) res putStrLn "Parallel test done" parallelTest :: (MonadEffects '[Async thread, NonDeterminism] m, MonadIO m) => m (thread 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 thread] 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") )