import Data.Array.MArray
import Data.Array.IO
import Data.IORef
import Control.Monad
a @@ i = readArray a i
a @@@ i = writeArray a i
copyTo a ifrom ito = do
x <- a @@ ifrom
(a @@@ ito) x
arrlength a = (getBounds a) >>= \(low,high) -> return $ high-low+1
whileM condition action = condition >>= flip when (action >> whileM condition action)
tec t e c = if c then t else e
andM cond1 cond2 = cond1 >>= tec cond2 (return False)
mfmap fn m = m >>= \x -> return $ fn x
insertSort :: (MArray a e IO, Ord e) => a Int e -> IO (a Int e)
insertSort a = do
len <- arrlength a
forM_ [1..len-1] $ \j -> do
key <- a @@ j
iref <- newIORef $ j - 1
let readi = readIORef iref
whileM (readi >>= \i -> (andM (return (i > -1)) (mfmap (>key) (a @@ i)))) $ do
i <- readi
copyTo a i (i+1)
modifyIORef iref (subtract 1)
i <- readi
(a @@@ (i+1)) key
return a
main = do
let listToSort = [1,3,6,3,5,8,2,4]
a <- newListArray (0,length listToSort-1) listToSort :: IO (IOUArray Int Int)
result <- insertSort a
resultList <- getElems a
putStrLn $ "result: "++show resultList