module ImpList where
import Control.Monad.ST
import Data.STRef
import Data.Array.ST
import Data.Array.MArray
data MyList s a = MyList (STRef s [a])
listToMyList :: [a] -> ST s (MyList s a)
listToMyList xs = do
ref <- newSTRef xs
return $ MyList ref
myListToList :: MyList s a -> ST s [a]
myListToList (MyList ref) =
readSTRef ref
appendListToMyList :: MyList s a -> [a] -> ST s ()
appendListToMyList (MyList ref) ys = do
xs <- readSTRef ref
let xs' = xs ++ ys
writeSTRef ref xs'
return ()
id :: [a] -> [a]
id xs = myListBuildingToList (\ ixs -> appendListToMyList ixs xs)
myListBuildingToList :: (forall s . MyList s a -> ST s ()) -> [a]
myListBuildingToList m =
runST (do ixs <- listToMyList []
() <- m ixs
myListToList ixs)
put :: MyList s a -> a -> ST s ()
put (MyList ref) x = do
xs <- readSTRef ref
let xs' = xs ++ [x]
writeSTRef ref xs'
return ()
-- put at front of list
put' :: MyList s a -> a -> ST s ()
put' (MyList ref) x = do
xs <- readSTRef ref
let xs' = [x] ++ xs
writeSTRef ref xs'
return ()
get :: MyList s a -> ST s (Maybe a)
get (MyList ref) = do
ix <- readSTRef ref
case ix of
[] -> return $ Nothing
(x:xs) -> do
writeSTRef ref xs
return $ Just x
test = do
lst <- listToMyList [4,5]
put lst 1
put lst 2
put lst 3
vs <- sequence $ take 10 $ repeat (get lst)
return vs
------------------------------------------------------------------------------