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 ------------------------------------------------------------------------------