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