This is a multi-part message in MIME format.
--------------EBB527FEAD30E684DE2E6D05
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

Here is begginings of my second attempt for an STL like library for
Haskell.  The only think this version has is Arrays however I plan to
add a lot more.  I am almost done with a mutable hash table and I plan
on adding incorporating in other containers such as Ordered Map, Sets,
and Bags, Queues, Dequeues and other similar stuff.  I also plan on
working on a general algorithm collection.  I will implement both purely
functional containers and truly mutable ones.

This version will compile under ghc 4.02 without optimization and the
June 27 CVS version of ghc with Optimizations.  It will also work
through hugs provided you run the files through hscpp.  Unlike Edition I
will strive to making sure that my library always makes it through the
latest version of Hugs.

The file Main.hs contains a small test script demonstrating how
PrimArrays can be faster than arrays with bound checking.  Although it
is difficult to tell, as the garbage collector gets in the way of my
benchmarks, accumPrimArray is about 50% to 33% faster than the normal
accumArray and my implementation of accumArray also seams to be a little
faster than GHC implantation.  I tried profiling the various accums
however I can't seam to get meaningful results form  the CVS version of
ghc.  (Is the profiler still not working correctly or is it me?).

I am very serious about hammering out a nice STL like library for
Haskell so I would be very interested in early feedback from some of you
Haskell experts out there.

I have attached some of the more interesting files from my library.  The
complete set can be found at http://metalab.unc.edu/kevina/abs.tar.

Once again feed back most welcome, especially from the Haskell experts
out on the list.
-- 
Kevin Atkinson
[EMAIL PROTECTED]
http://metalab.unc.edu/kevina/
--------------EBB527FEAD30E684DE2E6D05
Content-Type: text/plain; charset=us-ascii;
 name="Container.hs"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="Container.hs"

module Container where

import Prelude hiding (null)

{- Basic container functions. -}

class Name c where
    name :: c -> String

class Size c where
    size     :: c -> Int

class Empty c where
    empty    :: c

class Null c where
    null     :: c -> Bool
    isEmpty  :: c -> Bool

    null = isEmpty
    isEmpty = null

class Values c v where
    values :: c v -> [v]

class ValMap c v1 v2 where
    valmap :: (v1 -> v2) -> c v1 -> c v2

instance (Functor c) => ValMap c v1 v2 where
    valmap = fmap

--------------EBB527FEAD30E684DE2E6D05
Content-Type: text/plain; charset=us-ascii;
 name="Assoc.hs"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="Assoc.hs"


module Assoc where

{- 

Functions on Associated Containers (Assoc. C.).  A Simple Assoc. C.
is a container which is indexed based on the value of its
elements such as Sets and Bags.  A Pair Assoc. C. is a Finite Map.

-}

import Container (ValMap(..))
import Prelude hiding (lookup)
import Maybe

class Buckets c where
    -- the number of buckets in a hash table
    buckets :: c -> Int

class Bounds c i e where
    -- the bounds of an array
    bounds :: c i e -> (i,i)

class Assocs c i e where
    -- convert a container to a list of ...
    assocs  :: c i e -> [(i,e)]
    indices :: c i e -> [i]
    keys    :: c i e -> [i]
    elems   :: c i e -> [e]

    -- minimal definition: assocs | indices & elems | keys & elems
    -- keys and indices are assumed to do the same thing
               
    assocs c = zip (indices c) (elems c)
    indices = map fst . assocs
    keys    = indices
    elems   = map snd . assocs

class Lookup c i e where
    -- finds an elemant in a Pair. Assoc. C.  (!) will cause an error
    -- if the element is not found
    lookup  :: i -> c i e -> Maybe e
    (!)     :: c i e -> i -> e

    -- monmal defination: lookup
                          
    c ! a = fromJust (lookup a c)

class Find c v where
    find :: v -> c v -> Maybe v
    findAll :: v -> c v -> [v]  
    isMember :: v -> c v -> Bool
    count :: v -> c v -> Int

    -- minimal defination: find | findAll

    find v c = listToMaybe$ findAll v c
    findAll v c = maybeToList$ find v c
    isMember v c = isJust$ find v c
    count v c = length$ findAll v c

class Ixmap c i e j where
    ixmap   :: (j,j) -> (i -> j) -> c i e -> c j e

class Keymap c i e j where
    keymap   :: (i -> j) -> c i e -> c j e

class Elmap c i e f where
    elmap   :: (e -> f) -> c i e -> c i f
    map_    :: ((i,e) -> f) -> c i e -> c i f

    -- minimal defination: map_

    elmap f = map_ (\(_,e) -> f e)

instance (Elmap c i e f) => ValMap (c i) e f where
    valmap = elmap

class AssocsMap c i e j f where
    assocsMap :: ((i,e) -> (j,f)) -> c i e -> c j f

class Insert c v where
    -- insert a new element in a Simple Assoc. C.  
    -- the behavinor of inserting an element that already exisits
    -- is implentation dependent (but NOT undefined)
    insert :: v -> c v -> c v
    insertMany :: [v] -> c v -> c v

    -- minimal defination: insert | insertMany

    insert v = insertMany [v]
    insertMany l c = foldr insert c l

class Replace c i e where
    -- inserts an key-value pair in a Pair Assoc. C.  If the key
    -- already exists replace its value with the new one.
    replace :: (i,e) -> c i e -> c i e
    replaceMany :: [(i,e)] -> c i e -> c i e

    -- minimal defination: replace | replaceMany

    replace v = replaceMany [v]
    replaceMany l c = foldr replace c l

class Remove c v where
    remove :: v -> c v -> c v       -- remove a single element that matches
    removeAll :: v -> c v -> c v    -- remove ALL elements that match
    removeMany :: [v] -> c v -> c v

    -- minimal defination: remove | removeMany

    remove v = removeMany [v]
    removeAll = remove
    removeMany l c = foldr remove c l

class Erase c i e where
    erase :: i -> c i e -> c i e
    eraseMany :: [i] -> c i e -> c i e
 
    -- minimal defination: erase | eraseMany

    erase i = eraseMany [i] 
    eraseMany l c = foldr erase c l

{- If accum is like fold1 then accum0 is like fold -}

class Accum c i e where
    accum :: (e -> f -> e) -> c i e -> [(i,f)] -> c i e

class Accum0 c i e where
    accum0 :: (e -> f -> e) -> e -> c i e -> [(i,f)] -> c i e




--------------EBB527FEAD30E684DE2E6D05
Content-Type: text/plain; charset=us-ascii;
 name="Mutable.hs"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="Mutable.hs"

module Mutable where

import Maybe
import Monad (liftM)

-- basic mutable refrence

infix 0 =~
class (Monad s) => Reference r v s where
    ref  :: v -> s (r v)
    val  :: r v -> s v
    (=~) :: r v -> v -> s ()

class (Monad s) => MShow a s where
    mshow :: a -> s String

class (Monad s) => MEq a s  where
    (==~), (/=~)    :: a -> a -> s Bool

        -- Minimal complete defintion:
        --      (==) or (/=)
    x /=~ y           =  liftM not (x ==~ y)
    x ==~ y           =  liftM not (x /=~ y)


class (MEq a s, Monad s) => MOrd a s  where
    mcompare                 :: a -> a -> s Ordering
    (<~), (<=~), (>=~), (>~) :: a -> a -> s Bool
    mmax, mmin               :: a -> a -> s a

        -- Minimal complete definition:
        --      (<=) or compare
        -- Using compare can be more efficient for complex types.
    mcompare x y = 
             do i <- x ==~ y 
                if i then return EQ else do 
                  i <- x <=~ y 
                  if i then return LT else do
                    return GT

    x <=~ y           =  liftM (/= GT) $ mcompare x y
    x <~  y           =  liftM (== LT) $ mcompare x y
    x >=~ y           =  liftM (/= LT) $ mcompare x y
    x >~  y           =  liftM (== GT) $ mcompare x y

 --note that (min x y, max x y) = (x,y) or (y,x)
    mmax x y = 
        do i <- x >=~ y
           if i then return x else return y
    mmin x y =
        do i <- x <~ y
           if i then return x else return y

-- basic container

class (Monad s) => MSize m s where
    msize :: m -> s Int

class (Monad s) => MNull m s where
    mnull, misEmpty :: m -> s Bool

    mnull = misEmpty
    misEmpty = mnull

class (Monad s) => MValues m v s where
    mvalues :: m v -> s [v]

class (Monad s) => MValMap m v1 v2 s where
    mvalmap :: (v1 -> v2) -> m v1 -> s (m v2)

class (Monad s) => MFunctor m s where
    mfmap :: (v1 -> v2) -> m v1 -> s (m v2)

class SelfMap m v s where
    selfMap :: (v -> v) -> m v -> s ()

class (Monad s) => MResize m s where
    mresize :: m -> Int -> s ()

class (Monad s) => MDontResize m s where
    mdontResize :: m -> s ()

class (Monad s) => FreezeThaw c m s where
    freeze, unsafeFreeze :: m -> s c
    thaw :: c -> s m

-- assoc container

class (Monad s) => MBuckets m s where
    mbuckets :: m -> s Int

class (Monad s) => MBounds c i e s where
    mbounds :: c i e -> s (i,i)

class (Monad s) => MAssocs c i e s where
    massocs         :: c i e -> s [(i,e)]
    mindices, mkeys :: c i e -> s [i]
    melems          :: c i e -> s [e]
             
    massocs  c = do i <- mindices c; e <- melems c; return (zip i e)
    mindices c = liftM (map fst) (massocs c)
    mkeys      = mindices
    melems   c = liftM (map snd) (massocs c)

class (Monad s) => MLookup m i e s where
    (!~) :: m i e -> i -> s e
    mlookup :: i -> m i e -> s (Maybe e)

    (!~) m k = liftM fromJust (mlookup k m)

class (Monad s) => MFind m v s where
    mfind :: v -> m v -> s (Maybe v)
    mfindAll :: v -> m v -> s [v]
    misMember :: v -> m v -> s Bool
    mcount :: v -> m v -> s Int

    mfind v m = liftM listToMaybe (mfindAll v m)
    mfindAll v m = liftM maybeToList (mfind v m)
    misMember v m = liftM isJust (mfind v m)
    mcount v m = liftM length (mfindAll v m)

class (Monad s) => MElmap c i e f s where
    melmap   :: (e -> f) -> c i e -> s (c i f)
    mmap_    :: ((i,e) -> f) -> c i e -> s (c i f)

    melmap f = mmap_ (\(_,e) -> f e)

instance (MElmap c i e f s) => MValMap (c i) e f s where
    mvalmap = melmap

-- The number returned is the change in size of the container for MInsert*
-- and MDel*

class (Monad s) => MInsert m v s where
    minsert :: v -> m v -> s Int
    minsertMany :: [v] -> m v -> s Int

    minsert v = minsertMany [v]
    minsertMany l m = mapM (`minsert` m) l >>= return . foldl (+) 0

class (Monad s) => MReplace m i e s where
    mreplace :: (i,e) -> m i e -> s Int
    mreplaceMany :: [(i,e)] -> m i e -> s Int

    mreplace v = mreplaceMany [v]
    mreplaceMany l m = mapM (`mreplace` m) l >>= return . foldl (+) 0

class (Monad s) => MRemove m v s where
    mremove :: v -> m v -> s Int
    mremoveAll :: v -> m v -> s Int
    mremoveMany :: [v] -> m v -> s Int

    mremove v = mremoveMany [v]
    mremoveAll = mremove
    mremoveMany l m = mapM (`mremove` m) l >>= return . foldl (+) 0

class (Monad s) => MErase m i e s where
    merase :: i -> m i e -> s Int
    meraseMany :: [i] -> m i e -> s Int

    merase v = meraseMany [v]
    meraseMany l m = mapM (`merase` m) l >>= return . foldl (+) 0

class (Monad s) => MZap m i e s where
    mzap :: i -> (e -> e) -> m i e -> s ()

instance (MZap0 m i e s) => MZap m i e s where
    mzap i f m = mzap0 i f undefined m

class (Monad s) => MZap0 m k d s where
    mzap0 :: k -> (d -> d) -> d -> m k d -> s ()

instance (MLookup m i e s, MReplace m i e s) => MZap0 m i e s where
    mzap0 ix f init m = do x <- mlookup ix m
                           case x of
                             Just e  -> mreplace (ix,f e) m
                             Nothing -> mreplace (ix,f init) m
                           return ()

class (Monad s) => MAccum m i e s where
    maccum :: (e -> f -> e) -> m i e -> [(i,f)] -> s ()

instance (MZap m i e s) => MAccum m i e s  where
    maccum f m l = z l
        where z []        = return ()
              z ((k,d):t) = do mzap k (`f` d) m; z t

class (Monad s) => MAccum0 m a b s where
    maccum0 :: (b -> c -> b) -> b -> m a b -> [(a,c)] -> s ()

instance (MZap0 m i e s) => MAccum0 m i e s  where
    maccum0 f init m l = do mapM_ (\(k,d)->mzap0 k (`f` d) init m) l; return ()






--------------EBB527FEAD30E684DE2E6D05
Content-Type: text/plain; charset=us-ascii;
 name="STExtras.hs"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="STExtras.hs"


module STExtras (unsafeRun', runST, ST, NT) where

import ST 
import IOExts

#ifdef __GLASGOW_HASKELL__

import PrelGHC

type NT = RealWorld

#else

type NT = ()

#endif

unsafeRun' :: ST NT a -> a
unsafeRun' a = unsafePerformIO$ stToIO a


--------------EBB527FEAD30E684DE2E6D05
Content-Type: text/plain; charset=us-ascii;
 name="PrimArrayDefn.hs"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="PrimArrayDefn.hs"


module PrimArrayDefn (module PrimArrayDefn, ST, module STExtras) where

{-
  A primative array is an array which has an index starting from 0,
  and does NOT do bound checkings unless lookup is used.  The index
  type is ALWAYS an Int.
-}

import Monad

import STExtras
import ST
import Mutable

import Container (Name(..),Size(..))
import Assoc (Bounds(..))

#ifdef __GLASGOW_HASKELL__

import Assoc (Assocs(elems))
import PrelGHC
import PrelBase
import PrelST

data MutPrimArray s i e = M (MutableArray# s e) Int#
data PrimArray      i e = A (Array# e)          Int#

#else

import Array hiding (bounds)

data MutPrimArray s i e = M (STArray s Int e) !Int
data PrimArray      i e = A (Array Int e)     !Int

#endif

instance Name (MutPrimArray s Int el) where
    name _ = "MutPrimArray"

instance Name (PrimArray Int el) where
    name _ = "PrimArray"

mshow' :: (MBounds a b c d, Name (a b c), Show b, Show c, MAssocs a b c d) => 
           a b c -> d String
mshow' arr = do 
    b <- mbounds arr
    a <- melems arr
    return$ name arr ++ " " ++ show b ++ " " ++ show a

(==*) :: (MSize (c Int el) s, MSize (d Int el) s, 
          Eq el, 
          MAssocs c Int el s, MAssocs d Int el s) =>
         c Int el -> d Int el -> s Bool
(==*) a b = do
    r <- liftM2 (==) (msize a) (msize b)
    if r then return True else do
      liftM2 (==) (melems a) (melems b)

mcompare' :: (MSize (c Int el) s, MSize (d Int el) s, 
              Ord el, 
              MAssocs c Int el s, MAssocs d Int el s) =>
             c Int el -> d Int el -> s Ordering
mcompare' a b = do
    r <- liftM2 compare (msize a) (msize b)
    return r
    case r of
      EQ -> liftM2 compare (melems a) (melems b)
      x  -> return x

mbounds' :: (Monad s, Size c) => c -> s (Int,Int)
mbounds' a = return (0,size a-1)

mindices' :: (Monad a, Size b) => b -> a [Int]
mindices' a = return [0..(size a-1)]

melems' :: (Size (c Int el), MLookup c Int el s) => c Int el -> s [el]
melems' a = do i <- mindices' a; mapM (a !~) i

instance MZap (MutPrimArray s) Int el (ST s) where
    mzap i f m = do x <- m !~ i; mreplace (i,f x) m; return ()    

instance SelfMap (MutPrimArray s Int) el (ST s) where
    selfMap f a = do i <- mindices' a; mapM (\x->mzap x f a) i; return ()

mmap_' :: (MSize (c Int el) (ST s), 
           MAssocs c Int el (ST s)) => 
           ((Int,el) -> el') -> c Int el -> ST s (MutPrimArray s Int el')
mmap_' f a = do
    s <- msize a
    l <- massocs a
    mlistPrimArray s (map f l)

{- constructors -}

mprimArray :: Int -> [(Int,el)] -> ST s (MutPrimArray s Int el)
mprimArray s l = do 
    m <- newArray s
    mreplaceMany l m
    return m

minitPrimArray :: el -> Int -> ST s (MutPrimArray s Int el)
minitPrimArray init s = do
    m <- newArray s
    let f ix | ix == s   = return ()
             | otherwise = do mreplace (ix,init) m; f (ix+1)
    f 0
    return m


maccumPrimArray :: (el -> el' -> el) -> el -> Int -> [(Int,el')]
                -> ST s (MutPrimArray s Int el)
maccumPrimArray f i s l = do 
    m <- minitPrimArray i s
    maccum f m l
    return m

mlistPrimArray :: Int -> [el] -> ST s (MutPrimArray s Int el)
mlistPrimArray s l = do
    m <- newArray s
    mreplaceMany (zip [0..] l) m
    return m

#ifdef __GLASGOW_HASKELL__

instance MSize (MutPrimArray s Int el) (ST s) where
    msize (M _ s) = return$ I# s

instance (Monad mon) => MSize (PrimArray Int el) mon where
    msize (A _ s) = return$ I# s

instance Size (MutPrimArray s Int el) where
    size (M _ s) = I# s

instance Bounds (MutPrimArray s) Int el where
    bounds (M _ s) = (0, I# (s -# 1#) )

instance MLookup (MutPrimArray s) Int el (ST s) where
    (!~) (M a _) (I# i) = ST$ \s -> readArray# a i s
    mlookup (I# i) (M a s) | i <# 0# || i >=# s = return Nothing
                           | otherwise          = (ST$ \s -> readArray# a i s)
                                                  >>= return . Just

#if __GLASGOW_HASKELL__ >= 404 
#define EL (# el #)
#else
#define EL (# _, el #)
#endif

instance (Monad mon) => MLookup PrimArray Int el mon where
    (!~) (A a _) (I# i) = return$ case indexArray# a i of EL -> el
    mlookup (I# i) (A a s) | i <# 0# || i >=# s = return Nothing
                           | otherwise          = return$ Just$ 
                                                  case indexArray# a i of 
                                                  EL -> el

#undef EL


instance MReplace (MutPrimArray s) Int el (ST s) where
    mreplace (I# i,e) (M a _) = ST$ \s -> (# writeArray# a i e s, 0 #)
    mreplaceMany l a = do mapM_ (`mreplace` a) l; return 0

instance MAccum (MutPrimArray s) Int el (ST s) where
    maccum f (M m _) l = ST$ \s -> (# z s l, () #)
        where z s [] = s
              z s ((I# ix,el):t) = 
                  case readArray# m ix s of
                  (# s, x #) -> case writeArray# m ix (x `f` el) s of
                                s -> z s t

unsafeFreeze' :: MutPrimArray s Int el -> ST s (PrimArray Int el)
unsafeFreeze' (M a s) = do a <- (ST$ \s -> unsafeFreezeArray# a s)
                           return$ A a s

--freeze' :: MutPrimArray s Int el -> ST s (PrimArray Int el)
freeze' a = melmap id a >>= unsafeFreeze'

--thaw' :: PrimArray Int el -> ST s (MutPrimArray s Int el)
thaw' a = mlistPrimArray (size a) (elems a)

newArray (I# size) = do m <- (ST$ \s -> newArray# size undefined s)
                        return$ M m size

#else

instance MSize (MutPrimArray s Int el) (ST s) where
    msize (M _ s) = return s

instance (Monad mon) => MSize (PrimArray Int el) mon where
    msize (A _ s) = return s

instance Size (MutPrimArray s Int el) where
    size (M _ s) = s

instance Bounds (MutPrimArray s) Int el where
    bounds (M _ s) = (0, s-1 )

instance MLookup (MutPrimArray s) Int el (ST s) where
    (!~) (M a _) i = readSTArray a i
    mlookup i (M a s) | i < 0 || i >= s = return Nothing
                      | otherwise       = fmap Just $ readSTArray a i 

instance (Monad mon) => MLookup PrimArray Int el mon where
    (!~) (A a _) i = return$ a ! i 
    mlookup  i (A a s) | i < 0 || i >= s = return Nothing
                       | otherwise       = return$ Just$ a ! i

instance MReplace (MutPrimArray s) Int el (ST s) where
    mreplace (i,e) (M a _) = do writeSTArray a i e; return 0

freeze' (M m s)       = do a <- freezeSTArray m;       return$ A a s
unsafeFreeze' (M m s) = do a <- unsafeFreezeSTArray m; return$ A a s
thaw' (A a s)         = do m <- thawSTArray a;         return$ M m s

newArray s = do m <- newSTArray (0,s-1) undefined
                return$ M m s

#endif

--------------EBB527FEAD30E684DE2E6D05
Content-Type: text/plain; charset=us-ascii;
 name="AltArrayDefn.hs"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="AltArrayDefn.hs"

module AltArrayDefn (module AltArrayDefn, module STExtras, 
                     module Ix, ST) where

import STExtras
import qualified PrimArrayFT as Prim
import MutPrimArray
import Mutable
import Container (Name(..), Size(..))
import Assoc (Bounds(..), Assocs(..))
import Ix
import Monad (liftM, liftM2)

-- needed because of GHC bug
import Eval

data (Ix i) => MutArray s i e = M (MutPrimArray s Int e) (i,i)
data (Ix i) =>    Array   i e = A (   PrimArray   Int e) (i,i)

instance Name (Array i e) where
    name _ = "array"

instance Name (MutArray s i e) where
    name _ = "mutArray"

mshow' :: (MBounds a b c d, Name (a b c), Show b, Show c, MAssocs a b c d) => 
           a b c -> d String
mshow' arr = do 
    b <- mbounds arr
    a <- massocs arr
    return$ name arr ++ " " ++ show b ++ " " ++ show a

(==*) :: (MBounds c ix el s, MBounds d ix el s, 
          Eq ix, Eq el, 
          MAssocs c ix el s, MAssocs d ix el s) =>
         c ix el -> d ix el -> s Bool
(==*) a b = do
    r <- liftM2 (==) (mbounds a) (mbounds b)
    if r then return True else do
      liftM2 (==) (melems a) (melems b)

mcompare' :: (MBounds c ix el s, MBounds d ix el s, 
              Ord ix, Ord el, 
              MAssocs c ix el s, MAssocs d ix el s) =>
             c ix el -> d ix el -> s Ordering
mcompare' a b = do
    r <- liftM2 compare (mbounds a) (mbounds b)
    return r
    case r of
      EQ -> liftM2 compare (melems a) (melems b)
      x  -> return x

msize' :: (MBounds c i e m, Ix i) => c i e -> m Int
msize' = liftM rangeSize . mbounds

instance (Ix ix) => Size (MutArray s ix el) where
    size (M _ r) = rangeSize r

instance (Ix ix) => Bounds (MutArray s) ix el where
    bounds (M _ r) = r

instance (Ix ix) => MBounds (MutArray s) ix el (ST s) where
    mbounds (M _ r) = return r

instance (Monad mon, Ix ix) => MBounds Array ix el mon where
    mbounds (A _ r) = return r

instance (Ix ix) => MAssocs (MutArray s) ix el (ST s) where
    mindices (M _ r) = return$ range r
    melems   (M a _) = melems a

instance (Ix ix, Monad mon) => MAssocs Array ix el mon where
    mindices (A _ r) = return$ range r
    melems   (A a _) = melems a

instance (Ix ix) => MLookup (MutArray s) ix el (ST s) where
    (!~) (M a r) i = a !~ index r i
    mlookup i (M a r) | inRange r i = liftM Just $ a !~ index r i
                      | otherwise   = return Nothing

instance (Monad mon, Ix ix) => MLookup Array ix el mon where
    (!~) (A a r) i = a !~ index r i
    mlookup i (A a r) | inRange r i = liftM Just $ a !~ index r i
                      | otherwise   = return Nothing

instance (Ix ix) => MReplace (MutArray s) ix el (ST s) where
    mreplace (i,e) (M a r) = mreplace (index r i,e) a

instance (Ix ix) => MZap (MutArray s) ix el (ST s) where
    mzap i f (M a r) = do let i' = index r i
                          x <- a !~ i'
                          mreplace (i',f x) a
                          return ()    

instance (Ix ix) => SelfMap (MutArray s ix) el (ST s) where
    selfMap f (M a _) = selfMap f a

instance (Ix ix) => MElmap (MutArray s) ix el el' (ST s) where
    mmap_  f aa@(M a r) = do l <- massocs aa
                             new <- mlistPrimArray (size a) (map f l)
                             return$ M new r

instance (Ix ix, Monad mon) => MElmap Array ix el el' mon where
    mmap_  f aa@(A a r) = do l <- massocs aa
                             let new = listPrimArray (size a) (map f l)
                             return$ A new r

freeze' (M a r) = do a <- Prim.freeze' a; return$ A a r
unsafeFreeze' (M a r) = do a <- Prim.unsafeFreeze' a; return$ A a r
thaw' (A a r) = do m <- Prim.thaw' a; return$ M m r

marray :: Ix a => (a,a) -> [(a,b)] -> ST c (MutArray c a b)
marray r l = do
    a <- mprimArray (rangeSize r) (map (\(i,e)->(index r i,e)) l)
    return$ M a r

mlistArray :: Ix a => (a,a) -> [b] -> ST c (MutArray c a b)
mlistArray r l = do
    let s = rangeSize r
    a <- mlistPrimArray s (take s l)
    return$ M a r

maccumArray :: Ix a => (b -> c -> b) -> b -> (a,a) -> [(a,c)] -> ST d (MutArray d a b)
maccumArray f i r l = do
    a <- maccumPrimArray f i (rangeSize r) (map (\(i,e)->(index r i,e)) l)
    return$ M a r

--------------EBB527FEAD30E684DE2E6D05
Content-Type: text/plain; charset=us-ascii;
 name="Main.hs"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="Main.hs"


module Main where

import Prelude hiding (null, lookup)

import Mutable
import Assoc
import Container

import MutPrimArray
import MutAltArray 
import STExtras

import Random

import qualified Array
import Ix

#ifdef __GLASGOW_HASKELL__

import Eval -- this should really not be necessary, however the CVS
            -- version of ghc (June 27, 1999) requires it. 
            -- I think it is a bug.

import CPUTime

num :: Int
num = 100000

#define scc(n) _scc_ n

#else

getCPUTime :: IO Integer
getCPUTime = return 0

num :: Int
num = 1000

#define scc(n)

#endif

l :: [Int]
l = take num$ randomRs (0,98) (mkStdGen 13)

main :: IO ()
main = do bench$ print$ scc("gen") seq (length (show l)) "Evaluating l"
          bench$ scc("orig") orig l
          bench$ scc("prim") prim l
          bench$ scc("norm") norm l

bench com = do s <- getCPUTime
               com
               f <- getCPUTime
               print$ (f-s) `div` (10^9)

prim l = do let a :: PrimArray Int Int
                a = accumPrimArray (+) 0 100 $ zip l (repeat 1)
            putStr "prim\n"
            print$ elems a

norm l = do let a :: Array Int Int
                a = accumArray (+) 0 (0,99) $ zip l (repeat 1)
            putStr "norm\n"
            print$ elems a

orig l = do let a :: Array.Array Int Int
                a = Array.accumArray (+) 0 (0,99) $ zip l (repeat 1)
            putStr "orig\n"
            print$ Array.elems a

--------------EBB527FEAD30E684DE2E6D05--



Reply via email to