2023-04-10 15:37:08 -04:00
|
|
|
{-# LANGUAGE RecursiveDo #-}
|
2023-04-10 22:32:12 -04:00
|
|
|
{-# OPTIONS_GHC -fplugin UIO #-}
|
2023-04-10 15:37:08 -04:00
|
|
|
module Test.UIO where
|
|
|
|
|
|
|
|
|
|
import Data.IORef
|
2023-04-10 17:41:45 -04:00
|
|
|
import Control.Monad
|
2023-04-10 15:37:08 -04:00
|
|
|
|
|
|
|
|
import UIO
|
2023-04-12 21:44:43 -04:00
|
|
|
import Test.UIO.MultiModule
|
2023-04-10 15:37:08 -04:00
|
|
|
|
2023-04-12 21:44:43 -04:00
|
|
|
test :: IO ()
|
|
|
|
|
test = do
|
2023-04-10 17:41:45 -04:00
|
|
|
putStrLn "testUIOFix"
|
2023-04-10 15:37:08 -04:00
|
|
|
testUIOFix
|
2023-04-10 17:41:45 -04:00
|
|
|
putStrLn "testUIOUnique"
|
2023-04-10 15:37:08 -04:00
|
|
|
testUIOUnique
|
2023-04-10 17:41:45 -04:00
|
|
|
putStrLn "testUIOReplicate"
|
|
|
|
|
testUIOReplicate
|
|
|
|
|
putStrLn "testUIOBadTimeless"
|
|
|
|
|
testUIOBadTimeless
|
|
|
|
|
putStrLn "testUIOMany"
|
2023-04-10 15:37:08 -04:00
|
|
|
testUIOMany
|
2023-04-10 22:26:20 -04:00
|
|
|
putStrLn "testUIOCycle"
|
|
|
|
|
testUIOCycle
|
2023-04-10 17:41:45 -04:00
|
|
|
putStrLn "testIO"
|
2023-04-10 15:37:08 -04:00
|
|
|
testIO
|
2023-04-12 21:44:43 -04:00
|
|
|
putStrLn "testMultiModule"
|
|
|
|
|
testMultiModule
|
2023-04-10 22:26:20 -04:00
|
|
|
-- putStrLn "testUIOPrintLots"
|
|
|
|
|
-- testUIOPrintLots
|
2023-04-10 15:37:08 -04:00
|
|
|
|
2023-04-10 17:41:45 -04:00
|
|
|
{-# NOINLINE testUIOUnique #-}
|
|
|
|
|
testUIOUnique :: IO ()
|
|
|
|
|
testUIOUnique = do
|
2023-04-12 21:44:43 -04:00
|
|
|
r <- runUIO $ do
|
2023-04-10 17:41:45 -04:00
|
|
|
-- The following two lines can be merged by common subexpression elimination (CSE), which is very bad
|
|
|
|
|
r <- timeless $ newIORef 2
|
|
|
|
|
r2 <- timeless $ newIORef 2
|
|
|
|
|
-- Note that the following two lines must be different, otherwise they will *also* be merged by CSE, which will make the test appear to succeed!
|
|
|
|
|
unordered $ atomicModifyIORef' r $ \v -> (v + 5, ())
|
|
|
|
|
unordered $ atomicModifyIORef' r2 $ \v -> (v + 10, ())
|
|
|
|
|
pure r
|
2023-04-10 22:26:20 -04:00
|
|
|
7 <- readIORef r
|
|
|
|
|
pure ()
|
2023-04-10 17:41:45 -04:00
|
|
|
|
2023-04-10 15:37:08 -04:00
|
|
|
{-# NOINLINE testUIOFix #-}
|
|
|
|
|
testUIOFix :: IO ()
|
|
|
|
|
testUIOFix = do
|
2023-04-12 21:44:43 -04:00
|
|
|
r <- runUIO $ mdo
|
2023-04-10 15:37:08 -04:00
|
|
|
unordered $ atomicModifyIORef' r $ \v -> (v + 5, ())
|
2023-04-10 17:41:45 -04:00
|
|
|
r <- timeless $ newIORef 2
|
|
|
|
|
pure r
|
2023-04-10 22:26:20 -04:00
|
|
|
7 <- readIORef r
|
|
|
|
|
pure ()
|
2023-04-10 17:41:45 -04:00
|
|
|
|
|
|
|
|
{-# NOINLINE testUIOBadTimeless #-}
|
|
|
|
|
testUIOBadTimeless :: IO ()
|
|
|
|
|
testUIOBadTimeless = do
|
2023-04-12 21:44:43 -04:00
|
|
|
r <- runUIO $ mdo
|
2023-04-10 17:41:45 -04:00
|
|
|
timeless $ atomicModifyIORef' r $ \v -> (v + 5, ())
|
|
|
|
|
r <- timeless $ newIORef 2
|
2023-04-10 15:37:08 -04:00
|
|
|
pure r
|
2023-04-10 22:26:20 -04:00
|
|
|
2 <- readIORef r
|
|
|
|
|
pure ()
|
2023-04-10 15:37:08 -04:00
|
|
|
|
|
|
|
|
{-# NOINLINE testUIOMany #-}
|
|
|
|
|
testUIOMany :: IO ()
|
|
|
|
|
testUIOMany = do
|
2023-04-12 21:44:43 -04:00
|
|
|
r <- runUIO $ do
|
2023-04-10 17:41:45 -04:00
|
|
|
r <- timeless $ newIORef 0
|
2023-04-10 15:37:08 -04:00
|
|
|
unordered $ atomicModifyIORef' r $ \v -> (v + 1, ())
|
|
|
|
|
unordered $ atomicModifyIORef' r $ \v -> (v + 2, ())
|
|
|
|
|
unordered $ atomicModifyIORef' r $ \v -> (v + 3, ())
|
|
|
|
|
unordered $ atomicModifyIORef' r $ \v -> (v + 4, ())
|
|
|
|
|
unordered $ atomicModifyIORef' r $ \v -> (v + 5, ())
|
|
|
|
|
unordered $ atomicModifyIORef' r $ \v -> (v + 6, ())
|
|
|
|
|
unordered $ atomicModifyIORef' r $ \v -> (v + 7, ())
|
|
|
|
|
unordered $ atomicModifyIORef' r $ \v -> (v + 8, ())
|
|
|
|
|
unordered $ atomicModifyIORef' r $ \v -> (v + 9, ())
|
|
|
|
|
unordered $ atomicModifyIORef' r $ \v -> (v + 10, ())
|
|
|
|
|
pure r
|
2023-04-10 22:26:20 -04:00
|
|
|
55 <- readIORef r
|
|
|
|
|
pure ()
|
2023-04-10 15:37:08 -04:00
|
|
|
|
2023-04-10 17:41:45 -04:00
|
|
|
{-# NOINLINE testUIOReplicate #-}
|
|
|
|
|
testUIOReplicate :: IO ()
|
|
|
|
|
testUIOReplicate = do
|
2023-04-12 21:44:43 -04:00
|
|
|
rs <- runUIO $ do
|
2023-04-10 17:41:45 -04:00
|
|
|
rs <- replicateM 10 $ timeless $ newIORef 2
|
|
|
|
|
forM_ rs $ \r ->
|
|
|
|
|
unordered $ atomicModifyIORef' r $ \v -> (v + 5, ())
|
|
|
|
|
pure rs
|
2023-04-10 22:26:20 -04:00
|
|
|
70 <- fmap sum $ mapM readIORef rs
|
|
|
|
|
pure ()
|
|
|
|
|
|
|
|
|
|
{-# NOINLINE testUIOPrintLots #-}
|
|
|
|
|
testUIOPrintLots :: IO ()
|
2023-04-12 21:44:43 -04:00
|
|
|
testUIOPrintLots = runUIO $ do
|
2023-04-10 22:26:20 -04:00
|
|
|
replicateM_ 1000000 $ unordered $ putStrLn "Task"
|
|
|
|
|
|
|
|
|
|
newtype CycleRef = CycleRef (IORef CycleRef)
|
|
|
|
|
|
|
|
|
|
{-# NOINLINE testUIOCycle #-}
|
|
|
|
|
testUIOCycle :: IO ()
|
2023-04-12 21:44:43 -04:00
|
|
|
testUIOCycle = runUIO $ mdo
|
2023-04-10 22:26:20 -04:00
|
|
|
r <- timeless $ newIORef $ CycleRef r
|
|
|
|
|
pure ()
|
2023-04-10 15:37:08 -04:00
|
|
|
|
2023-04-12 21:44:43 -04:00
|
|
|
{-# NOINLINE testIO #-}
|
2023-04-10 15:37:08 -04:00
|
|
|
testIO :: IO ()
|
|
|
|
|
testIO = do
|
|
|
|
|
r <- newIORef 2
|
|
|
|
|
atomicModifyIORef' r $ \v -> (v + 5, ())
|
2023-04-10 22:26:20 -04:00
|
|
|
7 <- readIORef r
|
|
|
|
|
pure ()
|