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

When I asked if there was an STL like library available for Haskell the
short answer was no.  So I decided to create one.

Attached is a first draft of my attempt to come up with an abstraction. 
It currently encapsulates list and arrays.  I plan on encapsulates all
of Edison's data structures under this view once it come out.

It uses mutiparapter type classes and overlapping instances and at the
moment only compiles under "hugs -98 +o".  The main problem with GHC is
that it does not allow "type"s on partly applies types such as the
example given in the standard: "type List = []".

The module AltPrelude basically makes all of Haskell's standard list
functions methods and thus is expected to be used as the Standard
Prelude.  The rest of the modules are for the array abstraction.  The
file main.hs provides some simple examples.

Early feedback most welcome.  My intention is that something like this
will be used in Haskell 2.  If you know of a better way to do something
please tell me.

For those of you who don't know STL stands for Standard Template Library
and provided a very powerful collection of algorithms and containers for
C++.  Thrue the use of templates and iterators it provides an extremely
well thought out abstraction of many common containers and algorithms. 
An abstraction which I hope this Library will bring to Haskell.
-- 
Kevin Atkinson
[EMAIL PROTECTED]
http://metalab.unc.edu/kevina/
--------------D94C6EDB5EF90419BD64FA07
Content-Type: text/plain; charset=us-ascii;
 name="AltPrelude.hs"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="AltPrelude.hs"


module AltPrelude
 (
-- Normal prelude
    Bool(False, True),
    Maybe(Nothing, Just),
    Either(Left, Right),
    Ordering(LT, EQ, GT),
    Char, String, Int, Integer, Float, Double, Rational, IO,
--  List type: []((:),]
--  Tuple types: (,), (,,), etc.
--  Trivial type: ()
--  Functions: (->)
    (:),
    Eq((==), (/=)),
    Ord(compare, (<), (<=), (>=), (>), max, min),
    Enum(succ, pred, toEnum, fromEnum, enumFrom, enumFromThen,
         enumFromTo, enumFromThenTo),
    Bounded(minBound, maxBound),
    Num((+), (-), (*), negate, abs, signum, fromInteger),
    Real(toRational),
    Integral(quot, rem, div, mod, quotRem, divMod, toInteger),
    Fractional((/), recip, fromRational),
    Floating(pi, exp, log, sqrt, (**), logBase, sin, cos, tan,
             asin, acos, atan, sinh, cosh, tanh, asinh, acosh, atanh),
    RealFrac(properFraction, truncate, round, ceiling, floor),
    RealFloat(floatRadix, floatDigits, floatRange, decodeFloat,
              encodeFloat, exponent, significand, scaleFloat, isNaN,
              isInfinite, isDenormalized, isIEEE, isNegativeZero, atan2),
    Monad((>>=), (>>), return, fail),
    Functor(fmap),
    mapM, mapM_, sequence, sequence_, (=<<), 
    maybe, either,
    (&&), (||), not, otherwise,
    subtract, even, odd, gcd, lcm, (^), (^^), 
    fromIntegral, realToFrac, 
    fst, snd, curry, uncurry, id, const, (.), flip, ($), until,
    asTypeOf, error, undefined,
    seq, ($!),

    ReadS, ShowS,
    Read(readsPrec, readList),
    Show(showsPrec, showList),
    reads, shows, show, read, lex,
    showChar, showString, readParen, showParen,

    FilePath, IOError, ioError, userError, catch,
    putChar, putStr, putStrLn, print,
    getChar, getLine, getContents, interact,
    readFile, writeFile, appendFile, readIO, readLn,

    iterate, repeat, replicate, cycle,
    lines, words, unlines, unwords, 
    zip, zip3, zipWith, zipWith3, unzip, unzip3,

-- redefined and new classes and functions
    Name(), Size(), Empty(), Null(),
    Reverse(), Map(), DMap(), 
    Fold1(), Fold(), 
    Concat(), ConcatL(), 
    Filter(), TakeDrop(), TakeDropWhile(), 
    Elem(), IndexLookup(), Lookup(), 
    Ixmap(), DIxmap(), IxmapB(), DIxmapB(), Elmap(), DElmap(),
    ToList(), Assocs(), Bounds(), ToRevList(),
    FrontSeq(), BidirSeq(), 
    FromList(), FromListB(), FromElemList(), FromElemListB(),
    AccumFromList(), AccumFromListB(), Accum(),
    Insert(), Replace(), Remove(), Cons(), Snoc(), 
    and, or, any, all) where

import qualified Prelude
import Prelude hiding (map, foldr, foldl, foldr1, foldl1, head, tail, filter,
                       length, null, take, drop, splitAt, takeWhile, 
                       dropWhile, span, break, last, init, reverse, 
                       elem, notElem, lookup, scanr, scanl, scanr1, scanl1,
                       (!!), (++), concat, and, or, any, all)
import Ix

infixl 1 #
a # f = f a


{- 

poly. types naming convetions:

  c,d   - in/out container  
  a,b   - in/out contents of container and or single type
  e,f   - in/out elements  
  i,j   - in/out indixes
  cc,dd - in/out containers of containers

Class names in general are the name of the prinisable method with the first
letter capitalized. A capital B at the end stands for Bounded and are used
in the array classes.

-}

class Name c where
  name :: c -> String

class Size c where
  size     :: c -> Int
  length   :: c -> Int
  
  -- minimal definition: size or length

  size c   = length c
  length c = size c

class Empty c where
  empty    :: c

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

  -- minimual defination null or isEmpty

  null c    = isEmpty c
  isEmpty c = null c

class Reverse c where
  reverse :: c -> c

class Map c a b where
  map :: (a -> b) -> c a -> c b

-- Note: the scan functions should probably be broken out into a new
--   class.

class Fold1 c a where
  foldr1 :: (a -> a -> a) -> c a -> a
  foldl1 :: (a -> a -> a) -> c a -> a
  scanr1 :: (a -> a -> a) -> c a -> [a]
  scanl1 :: (a -> a -> a) -> c a -> [a]

class (Fold1 c a) => Fold c a b where
  foldr  :: (a -> b -> b) -> b -> c a -> b
  foldl  :: (b -> a -> b) -> b -> c a -> b
--foldl' :: (b -> a -> b) -> b -> c a -> b
  scanr  :: (a -> b -> b) -> b -> c a -> [b]
  scanl  :: (b -> a -> b) -> b -> c a -> [b]

class Concat c a where
  (++)   :: c a -> c a -> c a

class Concat c a => ConcatL cc c a where
  concat :: cc (c a) -> c a

class Filter c a where 
  filter :: (a -> Bool) -> c a -> c a

class TakeDrop c a where
  take, drop   :: Int -> c a -> c a
  splitAt      :: Int -> c a -> (c a, c a)

  -- minumal definition splitAT

  take i c = t where (t,_) = splitAt i c
  drop i c = d where (_,d) = splitAt i c

class TakeDropWhile c a where
  takeWhile, dropWhile :: (a -> Bool) -> c a -> c a
  span, break          :: (a -> Bool) -> c a -> (c a, c a)

  -- minimal definition span

  takeWhile f c = t where (t,_) = span f c
  dropWhile f c = d where (_,d) = span f c
  break     f   = span (not . f)

class Elem c a i where
  elem    :: i -> c a -> Bool
  notElem :: i -> c a -> Bool

  -- minimal definition elem

  notElem e c = not $ elem e c

infixl 9 !!, !

class IndexLookup c a where
  (!!) :: c a -> Int -> a

class Lookup c i e where
  lookup  :: i -> c (i,e) -> Maybe e
  (!)     :: c (i,e) -> i -> e

  c ! a = r where (Just r) = lookup a c

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

class IxmapB c i e j where
  ixmapB   :: (j,j) -> (i -> j) -> c (i,e) -> c (j,e)

class (DElmap c i e c f) => 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)

-- the D maps are like their normal maps except that they don't promise to
-- return the exact same type if there contents types change

class DMap c a d b where
  dmap :: (a -> b) -> c a -> d b

class DIxmap c i e d j where
  dixmap   :: (i -> j) -> c (i,e) -> d (j,e)

class DIxmapB c i e d j where
  dixmapB   :: (j,j) -> (i -> j) -> c (i,e) -> d (j,e)

class DElmap c i e d f where
  delmap   :: (e -> f) -> c (i,e) -> d (i,f)
  dmap_    :: ((i,e) -> f) -> c (i,e) -> d (i,f)

class ToList c a where
  toList     :: c a -> [a]

class (ToList c (i,e)) => Assocs c i e where
  assocs  :: c (i,e) -> [(i,e)]
  indices :: c (i,e) -> [i]
  elems   :: c (i,e) -> [e]

  assocs  = toList
  indices = map fst . toList
  elems   = map snd . toList

class Bounds c a b where
  bounds  :: c (a,b) -> (a,a)

class ToRevList c a where
  toRevList :: c a -> [a]

class (ToList c a) => FrontSeq c a where
  head     :: c a -> a
  tail     :: c a -> c a
  headtail :: c a -> (a, c a)
 
  head     c = h      where (h,_) = headtail c
  tail     c = t      where (_,t) = headtail c

class (FrontSeq c a) => BidirSeq c a where
  last     :: c a -> a
  init     :: c a -> c a
  lastinit :: c a -> (a, c a)

  last     c = l      where (l,_) = lastinit c
  init     c = i      where (_,i) = lastinit c

class FromList c a where
  fromList :: [a] -> c a

class FromListB c a b where
  fromListB :: (a,a) -> [(a,b)] -> c (a,b)

class FromElemList c a b where
  fromElemList :: [b] -> c (a,b)

class FromElemListB c a b where
  fromElemListB :: (a,a) -> [b] -> c (a,b)

class AccumFromList c a b e where
  accumFromList :: (b -> e -> b) -> b -> [(a,e)] -> c (a,b)

class AccumFromListB c a b e where
  accumFromListB :: (b -> e -> b) -> b -> (a,a) -> [(a,e)] -> c (a,b)

class Insert c a where
  insert     :: a   -> c a -> c a
  insertList :: [a] -> c a -> c a

  -- Minimum defination: insert or insertList

  insert     e     c = insertList [e] c
  insertList []    c = c
  insertList (h:t) c = insert h c # insertList t

infix 9 //

class Replace c a where
  replace     :: a   -> c a -> c a
  replaceList :: [a] -> c a -> c a
  (//)        :: c a -> [a] -> c a

  -- Minimum defination: replace or replaceList

  replace      e     c = replaceList [e] c
  replaceList []    c = c
  replaceList (h:t) c = replace h c # replaceList t
  c // l = replaceList l c

class Remove c a where
  remove     ::  e -> c a -> c a
  removeList :: [e] -> c a -> c a

  -- Minimum defination: remove or removeList

  remove     e     c = removeList [e] c
  removeList []    c = c
  removeList (h:t) c = remove h c # removeList t

class Accum c a b e where
  accum :: (b -> e -> b) -> c (a,b) -> [(a,e)] -> c (a,b)

class Empty (c a) => Cons c a where
  cons :: a -> c a -> c a

class Empty (c a) => Snoc c a where
  snoc :: a -> c a -> c a

-- Generic instances

-- Most all of them convert the container to a list and then use 
-- the standard prelude functions

-- Most of them will NOT be needed if Haskell supported some sort of 
-- implicit conversion method.

instance ToList c a => Size (c a) where
  size  c = toList c # Prelude.length

instance ToList c a => Null (c a) where
  null  c = toList c # Prelude.null

instance (Eq a, ToList c a) => 
           Eq (c a) where
  (==) a b = toList a == toList b

instance (Ord a, ToList c a) =>
           Ord (c a) where
  compare a b = compare (toList a) (toList b)

instance ToList c a => Fold1 c a where
  foldr1 f c   = toList c # Prelude.foldr1 f
  foldl1 f c   = toList c # Prelude.foldl1 f
  scanr1 f c   = toList c # Prelude.scanr1 f
  scanl1 f c   = toList c # Prelude.scanl1 f

instance ToList c a => Fold c a b where
  foldr  f i c = toList c # Prelude.foldr  f i
  foldl  f i c = toList c # Prelude.foldl  f i
  scanr  f i c = toList c # Prelude.scanr  f i
  scanl  f i c = toList c # Prelude.scanl  f i

instance (Eq a, ToList c a) => Elem c a a where
  elem    e c = toList c # Prelude.elem    e
  notElem e c = toList c # Prelude.notElem e

instance (Eq a, ToList c (a,b)) => Lookup c a b where
  lookup  e c = toList c # Prelude.lookup e

instance FrontSeq c a => ToList c a where
  toList c | null c    = []
           | otherwise = let (h,t) = headtail c
                         in  h : toList t

instance (FrontSeq c a, Cons c a) => BidirSeq c a where
  last     c | null t    = h
             | otherwise = last t
           where (h,t) = headtail c
  lastinit c | null t    = (h, empty)
             | otherwise = (l, h `cons` i)
           where (h,t) = headtail c
                 (l,i) = lastinit t

instance (Cons c a) => Insert c a where
  insert = cons

instance (ToList c a, FromList c b) => Map c a b where
  map     f c = toList c # Prelude.map f      # fromList


instance (ToList c a, FromList c a) => Concat c a where
  (++)    c d = let a = toList c; b = toList d
                in  a Prelude.++ b # fromList

instance (Fold d (c a) (c a), Concat c a) => ConcatL d c a where
  concat = foldl1 (++)

instance (ToList c a, FromList c a) => Filter c a where
  filter  f c = toList c # Prelude.filter f # fromList

instance (ToList c a, FromList c a) => Reverse (c a) where
  reverse   c = toList c # Prelude.reverse  # fromList

tmap2 :: (a -> b) -> (a,a) -> (b,b)
tmap2 f (a,b) = (f a, f b)

instance (ToList c a, FromList c a) => TakeDrop c a where
  take    i c = toList c # Prelude.take i    # fromList
  drop    i c = toList c # Prelude.drop i    # fromList
  splitAt i c = toList c # Prelude.splitAt i # tmap2 fromList

instance (ToList c a, FromList c a) => TakeDropWhile c a where
  takeWhile f c = toList c # Prelude.takeWhile f # fromList
  dropWhile f c = toList c # Prelude.dropWhile f # fromList
  span      f c = toList c # Prelude.span  f     # tmap2 fromList
  break     f c = toList c # Prelude.break f     # tmap2 fromList

instance (Map c a b) => DMap c a c b where
  dmap = map

{- For some reason thse cause overlapping instances errors with Hugs
   when the array classes.

instance (Ixmap c i e j) =>  DIxmap c i e c j where
  dixmap = ixmap

instance (IxmapB c i e j) => DIxmapB c i e c j where
  dixmapB = ixmapB

instance (Elmap c i e f) => DElmap c i e c f where
  delmap = elmap
  dmap_  = map_

-}

-- alt prelude function definations

and, or          :: Fold c Bool Bool => c Bool -> Bool
and              =  foldr (&&) True
or               =  foldr (||) False

any,all :: (Map c a Bool, Fold c Bool Bool) => (a -> Bool) -> c a -> Bool
any p            =  or . map p
all p            =  and . map p

-- list instances
-- These few specific instances provide enough information to use lists
-- with all the traditional functions you expect and then some.

instance Name [a] where
  name _ = "List"

instance ToList [] a where
  toList l = l

instance FromList [] a where
  fromList l = l

instance FrontSeq [] a where
  headtail (h:t) = (h,t)

instance Empty [a] where
  empty = []

instance Cons [] a where
  cons h t = (Prelude.:) h t

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


module AltArrayBase where

data ArrayView internal ixel = ArrayView internal

{- The data type for an ArrayView is purposely vague to allow for the 
   greatest flexibility.  The expected structure of the ArrayViews types 
   is. -}

type ArrayView_ inr st mut ix el = ArrayView (inr,(st (mut (ix,el)))) (ix,el)
type ArrayView_' inr st mut ix el = ArrayView (inr,(st (mut (ix,el))))

{- Where:
     inr - the internals of the ArrayView, what holds the actual data
     st  - the State Transformer parly applied without the data
           and without any univerally qualifed variables.  Ie. s is given 
           a name.
     mut - the mutable array partly type applied without (ix,el)
     ix  - the index type
     el  - the element type

This structure allays the necessary type information to be picked out of the
structure duren derived instances but has a simple type to the user of the
ArrayView data type.

It uses (ix,el) instead of (ix el) because doing it this way allows
classes which expect only a single type as the contents to get both
_ix_ and _el_ as a pair rather than just _el_.  Even though this may
not be as convinite it allows arrays to be treated as assosited pairs,
is a lot more powerful, and in my view the right way to do it.  I plan
on provding a VectorView which will be similar to an ArrayView except
that the indices are always Ints which start from 0 and the last type
is _el_ and not (ix,el).

More specific array views can me made by specifying all but ix and el.
A type which represents Haskell Arrays is provided in BasicArray.hs

Other possibility includes Arrays which allow constant time, non copying 
slices to be taken and arrays which can have spaced out indices such 
as [10,20,..,100].  Both of which have a varity of uses.

-}








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


module AltArray (module Ix, ArrayView) where

import qualified Prelude
import AltPrelude
import AltArrayBase
import AltMutableArray
import Ix

-- Generic ArrayView Instances

instance (Ix ix, Bounds (ArrayView inr) ix el) => 
           Size (ArrayView inr (ix,el)) where
  size c = rangeSize (bounds c)

instance (Ix ix, Eq ix, Eq el, 
          Bounds (ArrayView inr) ix el, Assocs (ArrayView inr) ix el) =>
           Eq (ArrayView inr (ix,el)) where
  (==) c d = bounds c == bounds d  &&  elems c == elems d

instance (Show ix, Show el,  Name (ArrayView inr (ix,el)),
          Bounds (ArrayView inr) ix el, Assocs (ArrayView inr) ix el) =>
           Show (ArrayView inr (ix,el)) where
   show c = name c ++ " " ++ show (bounds c) ++ " " ++ show (assocs c)

instance Name (ArrayView inr (ix,el)) where
   name c = "ArrayView"

instance (MutableArrayView inr st mut i e) => 
           FromListB (ArrayView_' inr st mut i e) i e where
  fromListB r l@((_,e):_) = createArray (mreplace l) r e

instance (MutableArrayView inr st mut i e) => 
           AccumFromListB (ArrayView_' inr st mut i e) i e f where
  accumFromListB f e r l = createArray proc r e
    where
    proc c = do {mreplace (zip (range r) (repeat e)) c; maccum f l c}

instance (MutableArrayView inr st mut i e) => 
           Accum (ArrayView_' inr st mut i e) i e f  where
  accum f arry l = procArray (maccum f l) arry

instance (MutableArrayView inr st mut i e) => 
           Replace (ArrayView_' inr st mut i e) (i,e)  where
  replaceList l arry = procArray (mreplace l) arry

find_minmax [(i,_)]   = (i,i)
find_minmax ((i,_):t) = (min i a,max i z) where (a,z) = find_minmax t

instance (Ix i, FromListB (ArrayView inr) i e) => 
           FromList (ArrayView inr) (i,e) where
  fromList l = fromListB (find_minmax l) l

instance (Ix i, AccumFromListB (ArrayView inr) i e f) =>
           AccumFromList (ArrayView inr) i e f  where
  accumFromList f e l = accumFromListB f e (find_minmax l) l

instance (FromList (ArrayView inr) (Int,e)) => 
           FromElemList (ArrayView inr) Int e where
  fromElemList l = fromList $ zip [0..] l

instance (Ix i, FromListB (ArrayView inr) i e) => 
           FromElemListB (ArrayView inr) i e where
  fromElemListB r l = fromListB r (zip (range r) l)

instance (Ix ix, Bounds (ArrayView inr) ix el) =>
           ToList (ArrayView inr) (ix,el) where
  toList c = [(i,c!i) | i <- range $ bounds $ c]

instance (Num ix, Ix ix, Bounds (ArrayView inr) ix el) => 
           Assocs (ArrayView inr) ix el where
  indices c = range $ bounds $ c
  elems c   = [c!i | i <- range $ bounds $ c]

instance (Ix ix, Bounds (ArrayView inr) ix el, Assocs (ArrayView inr) ix el,
          FromElemListB (ArrayView inr) ix el) =>  
           Elmap (ArrayView inr) ix el el where
  elmap f c = fromElemListB (bounds c) (map f (elems c))
  map_  f c = fromElemListB (bounds c) (map f (assocs c))

{- If the compiler can optimize the thaw*Array so that it doesn't
   actually have to make a copy than this implentation should be faster
   as it doesn't actually have to make a copy.  Otherwise it will probully
   be slightly slower becuase it has to write to the array twise -}

{- insert verion of Elmap that convertes to a mutable array -}

instance (Ix i, Bounds (ArrayView inr) i e, Assocs (ArrayView inr) i e,  
          FromElemListB (ArrayView inr') i f) =>  
           DElmap (ArrayView inr) i e (ArrayView inr') f where
  delmap f c = fromElemListB (bounds c) (map f (elems c))
  dmap_  f c = fromElemListB (bounds c) (map f (assocs c))

instance (Ix i, FromListB (ArrayView inr) i e, Assocs (ArrayView inr) i e) => 
           IxmapB (ArrayView inr) i e i where
  ixmapB b f c = fromListB b $ zip (map f (indices c)) (elems c)

instance (Ix i, FromListB (ArrayView inr) i e, Assocs (ArrayView inr) i e) => 
           Ixmap (ArrayView inr) i e i where
  ixmap f c = fromList $ zip (map f (indices c)) (elems c)


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


module AltMutableArray(ArrayView_, ArrayView_',  
                       ToFromMutableArray(), UnsafeRun(), MutableArray(),
                       MutableArrayView(), 
                       procArray, createArray, maccum, mreplace) where

import AltArrayBase

-- inr  - the internals of the ArrayView, what holds the actual data
-- st   - the State Transformer parly applied without the data
-- mut  - the mutable array partly applied without (ix,el)
-- ix,i  - the index type
-- el,e - the element type
-- c    - the contents of st

class ToFromMutableArray inr st mut ix el where
  thawArray         :: ArrayView_ inr st mut ix el -> st (mut (ix,el))
  unsafeFreezeArray :: mut (ix,el) -> st (ArrayView_ inr st mut ix el)

class UnsafeRun st c where
  unsafeRun :: st c -> c

infixl 9 -!, -/

class (Monad st) => MutableArray st mut ix el where
  newArray :: (ix,ix) -> el -> st (mut (ix,el))
  (-!)     :: mut (ix,el) -> ix -> st el
  (-/)     :: mut (ix,el) -> (ix,el) -> st ()
  mbounds  :: mut (ix,el) -> st (ix,ix)
  swap     :: (ix,ix) -> mut (ix,el) -> st ()

  swap (i,j) c = do {a <- (c -! i); b <- (c -! j); c -/ (i,b); c -/ (j,a)}

class (Ix ix, UnsafeRun st (ArrayView_ inr st mut ix el), Monad st, 
       ToFromMutableArray inr st mut ix el, MutableArray st mut ix el)
                                       => MutableArrayView inr st mut ix el
instance (Ix ix, UnsafeRun st (ArrayView_ inr st mut ix el), Monad st, 
       ToFromMutableArray inr st mut ix el, MutableArray st mut ix el)
                                       => MutableArrayView inr st mut ix el
procArray :: MutableArrayView inr st mut ix el
               => (mut (ix,el) -> st dc) -> ArrayView_ inr st mut ix el 
                                 -> ArrayView_ inr st mut ix el
procArray f arry = unsafeRun to_proc
  where
  to_proc = do {c <- thawArray arry; f c; unsafeFreezeArray c}

createArray :: MutableArrayView inr st mut ix el
               => (mut (ix,el) -> st dc) -> (ix, ix) -> el
                                 -> ArrayView_ inr st mut ix el
createArray f r e = unsafeRun to_proc
  where
  to_proc = do {c <- newArray r e; f c; unsafeFreezeArray c}


maccum :: (Monad st, MutableArray st mut i e)
                           => (e -> f -> e) -> [(i,f)] -> mut (i,e) -> st ()
maccum f l c = 
  sequence [do {e0 <- (c -! i); c -/ (i, f e0 e)} | (i,e) <- l] >> return ()

mreplace ::  (Monad st, MutableArray st mut i e)
                                         => [(i,e)] -> mut (i,e) -> st ()
mreplace l c = sequence [do {c -/ (i,e)} | (i,e) <- l] >> return ()



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


module BasicArray (module AltArray, 
                   array, listArray, accumArray,
                   BasicArray, BasicArray') where

{- This module -}

import qualified Prelude
import AltPrelude
import ST
import IOExts(unsafePerformIO)
import qualified Array as A
import Ix
import AltArray
import AltMutableArray

type BasicArray ix el = ArrayView (BasicGuts ix el) (ix,el)
type BasicArray' ix el = ArrayView (BasicGuts ix el)

-- convence constructors

array :: (FromListB (BasicArray' ix el) ix el) => 
           (ix,ix) -> [(ix,el)] -> BasicArray ix el
array r l = fromListB r l 

listArray :: (FromElemListB (BasicArray' ix el) ix el) => 
               (ix,ix) -> [el] -> BasicArray ix el
listArray r l = fromElemListB r l 

accumArray :: (AccumFromListB (BasicArray' i e) i e f) =>
                (e -> f -> e) -> e -> (i,i) -> [(i,f)] -> BasicArray i e
accumArray f e r l = accumFromListB f e r l

-- messay mutable array stuff

data AST = AST
data AltSTArray c ixel = AltSTArray c
type AltSTArray_  ix el = AltSTArray (STArray AST ix el) (ix,el)
type AltSTArray_' ix el = AltSTArray (STArray AST ix el)

type BasicGuts ix el = (A.Array ix el, ST AST (AltSTArray_ ix el))

instance UnsafeRun (ST s) c where
  unsafeRun s = unsafePerformIO (stToIO s)

instance (Ix ix) => 
           MutableArray (ST s) (AltSTArray (ST.STArray s ix el)) ix el where
  newArray r e = do {c <- newSTArray r e; return (AltSTArray c)}
  (AltSTArray mut) -! i = readSTArray mut i
  (AltSTArray mut) -/ (i,e) = writeSTArray mut i e
  mbounds (AltSTArray mut) = return (boundsSTArray mut)

instance (Ix ix) =>
           ToFromMutableArray (A.Array ix el) (ST AST) (AltSTArray_' ix el)
                              ix el   where
  thawArray (ArrayView (a,_)) = 
    do {c <- thawSTArray a; return (AltSTArray c)}
  unsafeFreezeArray (AltSTArray mut) =
    do {c <- unsafeFreezeSTArray mut; return (ArrayView (c,undefined))}

-- Other fundamental instances

instance (Ix ix) => 
           Lookup (BasicArray' ix el) ix el where
  (ArrayView (c,_)) ! i = c A.! i
  lookup i (ArrayView (c,_)) | inRange (A.bounds c) i = Just (c A.! i)
                             | otherwise              = Nothing

instance (Ix ix) => 
           Bounds (BasicArray' ix el) ix el where
  bounds (ArrayView (c,_)) = A.bounds c

instance Name (BasicArray ix el) where
  name _ = "BasicArray"

-- These instances are not really needed but for some really strange reason
-- the generic instances don't work in hugs

instance Ix ix => ToList (BasicArray' ix el) (ix,el) where
  toList (ArrayView (c,_)) = A.assocs c

instance Ix ix => Assocs (BasicArray' ix el) ix el where
  indices (ArrayView (c,_)) = A.indices c
  elems   (ArrayView (c,_)) = A.elems   c



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


import qualified Prelude
import AltPrelude
import BasicArray

a  = listArray (1,10) [10,20..]
b  = listArray (2,11) [10,20..]
al = zip [1..10] [10,20..]

main = 
  do print (a !5)
     print (al!5)
     print (size a == size al)
     print (a < b)
     print a
     print b
     print al

--------------D94C6EDB5EF90419BD64FA07--



Reply via email to