fork download
import Control.Monad (forM,forM_,(<=<),unless,replicateM)
import Data.Array.IO (IOUArray,newArray,newArray_,readArray,writeArray,freeze)
import Data.Array.Unboxed (listArray,Array,UArray,(!))
import Data.Int (Int64)
import Data.IORef (IORef,newIORef,readIORef,writeIORef,modifyIORef)
import Data.Ix

fooArray = newArray_ (0,3) :: IO (IOUArray Int Int64)

main = do
	let len = 3
	a <- newArray_ (0, len) :: IO (IOUArray Int Int64)
	putStrLn "print a"
	forM_ [0..len] (print <=< readArray a)
	forM_ [0..len] (\i -> writeArray a i (fromIntegral $ (i+1)*2))
	putStrLn "print updated a"
	forM_ [0..len] $ \i -> do
		v <- readArray a i
		print v
	
	rx <- newIORef (123 :: Int64)
	x <- readIORef rx -- copy value, not reference
	putStr "x "
	print x -- 123
	writeIORef rx 999
	putStr "x "
	print x -- 123
	x <- readIORef rx
	putStr "x "
	print x -- 999

	foo <- fooArray
	putStrLn "print foo"
	print =<< forM [0..len] (readArray foo)
	forM_ [0..len] (\i -> writeArray foo i (fromIntegral $ (i+1)*2))
	putStrLn "print updated foo"
	print =<< forM [0..len] (readArray foo)
	bar <- fooArray
	putStrLn "print bar"
	print =<< forM [0..len] (readArray bar)
	
	(primes, isPrime) <- primeTool (10^8)
	print (take 30 primes)
	print (filter isPrime [10^7..10^7+300])
	
	arr <- genIntArray 10 0
	forM_ [0..9] $ \i -> writeIORef (arr!i) (i*(i+1)`div`2)
	print =<< forM [0..9] (readIORef.(arr!))
	
	table <- genMatrix 5 5 0
	forM_ [0..4] $ \i -> do
		forM_ [0..4] $ \j -> do
			writeIORef (table!i!j) (i*100+j)
	print =<< forM [0..4] (\i -> forM [0..4] (readIORef.(table!i!)))



genArray :: (Integral a,Ix a) => a -> IO b -> IO (Array a b)
genArray n initf = listArray (0,n-1) <$> replicateM (fromIntegral n) initf

genIntArray :: (Integral a, Ix a) => Integral b => a -> b -> IO (Array a (IORef b))
genIntArray n initv = genArray n (newIORef initv)

genMatrix :: (Integral a, Ix a) => a -> a -> b -> IO (Array a (Array a (IORef b)))
genMatrix n m initv = genArray n (genArray m (newIORef initv))



primeTool n = do
    table <- newArray (0,n+6) False :: IO (IOUArray Int64 Bool)
    primes <- newIORef [3,2]
    forM_ [1..((n+5) `div` 6)] $ \i -> do
        let x = 6*i - 1
        r <- readArray table x
        unless r $ do
            modifyIORef primes (x:)
            forM_ [3,5..((n+5) `div` x)] $ \k -> do
                writeArray table (k*x) True
        let y = x + 2
        q <- readArray table y
        unless q $ do
            modifyIORef primes (y:)
            forM_ [3,5..((n+5) `div` y)] $ \k -> do
                writeArray table (k*y) True
        writeArray table (y+2) True
    
    writeArray table 1 True
    table <- freeze table :: IO (UArray Int64 Bool)
    primes <- reverse <$> readIORef primes
    
    let isPrime v | even v = v == 2
                  | v < n  = not (table!v)
                  | otherwise = all ((/=0).mod v) $ takeWhile ((<=v).(^2)) primes

    return (primes, isPrime)

Success #stdin #stdout 3.39s 585656KB
stdin
Standard input is empty
stdout
print a
0
0
0
0
print updated a
2
4
6
8
x 123
x 123
x 999
print foo
[0,0,0,0]
print updated foo
[2,4,6,8]
print bar
[0,0,0,0]
[2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113]
[10000019,10000079,10000103,10000121,10000139,10000141,10000169,10000189,10000223,10000229,10000247,10000253,10000261,10000271]
[0,1,3,6,10,15,21,28,36,45]
[[0,1,2,3,4],[100,101,102,103,104],[200,201,202,203,204],[300,301,302,303,304],[400,401,402,403,404]]