[project @ 2002-02-12 11:44:54 by simonmar]
[ghc-hetmet.git] / ghc / lib / std / Array.lhs
1 % -----------------------------------------------------------------------------
2 % $Id: Array.lhs,v 1.16 2001/04/14 22:27:00 qrczak Exp $
3 %
4 % (c) The University of Glasgow, 1994-2000
5 %
6 \section[Array]{Module @Array@}
7
8 \begin{code}
9 {-# OPTIONS -fno-implicit-prelude #-}
10
11 module  Array 
12
13     ( 
14       module Ix                 -- export all of Ix 
15     , Array                     -- Array type is abstract
16
17     , array         -- :: (Ix a) => (a,a) -> [(a,b)] -> Array a b
18     , listArray     -- :: (Ix a) => (a,a) -> [b] -> Array a b
19     , (!)           -- :: (Ix a) => Array a b -> a -> b
20     , bounds        -- :: (Ix a) => Array a b -> (a,a)
21     , indices       -- :: (Ix a) => Array a b -> [a]
22     , elems         -- :: (Ix a) => Array a b -> [b]
23     , assocs        -- :: (Ix a) => Array a b -> [(a,b)]
24     , accumArray    -- :: (Ix a) => (b -> c -> b) -> b -> (a,a) -> [(a,c)] -> Array a b
25     , (//)          -- :: (Ix a) => Array a b -> [(a,b)] -> Array a b
26     , accum         -- :: (Ix a) => (b -> c -> b) -> Array a b -> [(a,c)] -> Array a b
27     , ixmap         -- :: (Ix a, Ix b) => (a,a) -> (a -> b) -> Array b c -> Array a b
28
29     -- Array instances:
30     --
31     --   Ix a => Functor (Array a)
32     --   (Ix a, Eq b)  => Eq   (Array a b)
33     --   (Ix a, Ord b) => Ord  (Array a b)
34     --   (Ix a, Show a, Show b) => Show (Array a b)
35     --   (Ix a, Read a, Read b) => Read (Array a b)
36     -- 
37
38     -- Implementation checked wrt. Haskell 98 lib report, 1/99.
39
40     ) where
41 \end{code}
42
43 #ifndef __HUGS__
44
45 \begin{code}
46         ------------ GHC --------------------
47 import Ix
48 import PrelArr          -- Most of the hard work is done here
49         ------------ End of GHC --------------------
50 \end{code}
51
52 #else
53
54 \begin{code}
55         ------------ HUGS (rest of file) --------------------
56 import PrelPrim ( PrimArray
57                 , runST
58                 , primNewArray
59                 , primWriteArray
60                 , primReadArray
61                 , primUnsafeFreezeArray
62                 , primIndexArray
63                 )
64 import Ix
65 import List( (\\) )
66
67 infixl 9  !, //
68 \end{code}
69
70
71 %*********************************************************
72 %*                                                      *
73 \subsection{The Array type}
74 %*                                                      *
75 %*********************************************************
76
77
78 \begin{code}
79 data Array ix elt = Array (ix,ix) (PrimArray elt)
80
81 array :: Ix a => (a,a) -> [(a,b)] -> Array a b
82 array ixs@(ix_start, ix_end) ivs = runST (do
83   { mut_arr <- primNewArray (rangeSize ixs) arrEleBottom
84   ; mapM_ (\ (i,v) -> primWriteArray mut_arr (index ixs i) v) ivs 
85   ; arr <- primUnsafeFreezeArray mut_arr
86   ; return (Array ixs arr)
87   }
88   )
89  where
90   arrEleBottom = error "(Array.!): undefined array element"
91
92 listArray               :: Ix a => (a,a) -> [b] -> Array a b
93 listArray b vs          =  array b (zipWith (\ a b -> (a,b)) (range b) vs)
94
95 (!)                     :: Ix a => Array a b -> a -> b
96 (Array bounds arr) ! i  = primIndexArray arr (index bounds i)
97
98 bounds                  :: Ix a => Array a b -> (a,a)
99 bounds (Array b _)      =  b
100
101 indices           :: Ix a => Array a b -> [a]
102 indices           = range . bounds
103
104 elems             :: Ix a => Array a b -> [b]
105 elems a           =  [a!i | i <- indices a]
106
107 assocs            :: Ix a => Array a b -> [(a,b)]
108 assocs a          =  [(i, a!i) | i <- indices a]
109
110 (//)              :: Ix a => Array a b -> [(a,b)] -> Array a b
111 (//) a us           =  array (bounds a)
112                         ([(i,a!i) | i <- indices a \\ [i | (i,_) <- us]]
113                          ++ us)
114
115 accum             :: Ix a => (b -> c -> b) -> Array a b -> [(a,c)] -> Array a b
116 accum f           =  foldl (\a (i,v) -> a // [(i,f (a!i) v)])
117
118 accumArray        :: Ix a => (b -> c -> b) -> b -> (a,a) -> [(a,c)] -> Array a b
119 accumArray f z b  =  accum f (array b [(i,z) | i <- range b])
120
121 ixmap             :: (Ix a, Ix b) => (a,a) -> (a -> b) -> Array b c -> Array a c
122 ixmap b f a       =  array b [(i, a ! f i) | i <- range b]
123
124
125 instance (Ix a) => Functor (Array a) where
126     fmap f a = array (bounds a) [(i, f(a!i)) | i <- indices a]
127
128 instance (Ix a, Eq b) => Eq (Array a b) where
129     a == a'   =   assocs a == assocs a'
130
131 instance (Ix a, Ord b) => Ord (Array a b) where
132     a <= a'   =   assocs a <= assocs a'
133
134
135 instance  (Ix a, Show a, Show b) => Show (Array a b)  where
136     showsPrec p a = showParen (p > 9) (
137                     showString "array " .
138                     shows (bounds a) . showChar ' ' .
139                     shows (assocs a)                  )
140
141 instance  (Ix a, Read a, Read b) => Read (Array a b)  where
142     readsPrec p = readParen (p > 9)
143              (\r -> [(array b as, u) | ("array",s) <- lex r,
144                                        (b,t)       <- reads s,
145                                        (as,u)      <- reads t   ])
146
147 \end{code}
148 #endif