Add explicit `{-# LANGUAGE CPP, PackageImports #-}` pragmas
[packages/haskell2010.git] / Data / Array.hs
1 {-# LANGUAGE CPP, PackageImports #-}
2 #if __GLASGOW_HASKELL__ >= 701
3 {-# LANGUAGE Trustworthy #-}
4 #endif
5
6 module Data.Array (
7 -- * Immutable non-strict arrays
8 -- $intro
9 module Data.Ix -- export all of Ix
10 , Array -- Array type is abstract
11
12 -- * Array construction
13 , array -- :: (Ix a) => (a,a) -> [(a,b)] -> Array a b
14 , listArray -- :: (Ix a) => (a,a) -> [b] -> Array a b
15 , accumArray -- :: (Ix a) => (b -> c -> b) -> b -> (a,a) -> [(a,c)] -> Array a b
16 -- * Accessing arrays
17 , (!) -- :: (Ix a) => Array a b -> a -> b
18 , bounds -- :: (Ix a) => Array a b -> (a,a)
19 , indices -- :: (Ix a) => Array a b -> [a]
20 , elems -- :: (Ix a) => Array a b -> [b]
21 , assocs -- :: (Ix a) => Array a b -> [(a,b)]
22 -- * Incremental array updates
23 , (//) -- :: (Ix a) => Array a b -> [(a,b)] -> Array a b
24 , accum -- :: (Ix a) => (b -> c -> b) -> Array a b -> [(a,c)] -> Array a b
25 -- * Derived arrays
26 , ixmap -- :: (Ix a, Ix b) => (a,a) -> (a -> b) -> Array b c -> Array a b
27
28 -- * Specification
29
30 -- $code
31 ) where
32
33 import qualified "array" Data.Array as Array
34 import "array" Data.Array hiding (array, (//))
35 import "base" Data.Ix
36
37 {- $intro
38 Haskell provides indexable /arrays/, which may be thought of as functions
39 whose domains are isomorphic to contiguous subsets of the integers.
40 Functions restricted in this way can be implemented efficiently;
41 in particular, a programmer may reasonably expect rapid access to
42 the components. To ensure the possibility of such an implementation,
43 arrays are treated as data, not as general functions.
44
45 Since most array functions involve the class 'Ix', the contents of the
46 module "Data.Ix" are re-exported from "Data.Array" for convenience:
47 -}
48
49 -- SDM: copied documentation for 'array' to remove GHC reference
50
51 -- | Construct an array with the specified bounds and containing values
52 -- for given indices within these bounds.
53 --
54 -- The array is undefined (i.e. bottom) if any index in the list is
55 -- out of bounds. If any
56 -- two associations in the list have the same index, the value at that
57 -- index is undefined (i.e. bottom).
58 --
59 -- Because the indices must be checked for these errors, 'array' is
60 -- strict in the bounds argument and in the indices of the association
61 -- list, but non-strict in the values. Thus, recurrences such as the
62 -- following are possible:
63 --
64 -- > a = array (1,100) ((1,1) : [(i, i * a!(i-1)) | i <- [2..100]])
65 --
66 -- Not every index within the bounds of the array need appear in the
67 -- association list, but the values associated with indices that do not
68 -- appear will be undefined (i.e. bottom).
69 --
70 -- If, in any dimension, the lower bound is greater than the upper bound,
71 -- then the array is legal, but empty. Indexing an empty array always
72 -- gives an array-bounds error, but 'bounds' still yields the bounds
73 -- with which the array was constructed.
74 array :: Ix i
75 => (i,i) -- ^ a pair of /bounds/, each of the index type
76 -- of the array. These bounds are the lowest and
77 -- highest indices in the array, in that order.
78 -- For example, a one-origin vector of length
79 -- '10' has bounds '(1,10)', and a one-origin '10'
80 -- by '10' matrix has bounds '((1,1),(10,10))'.
81 -> [(i, e)] -- ^ a list of /associations/ of the form
82 -- (/index/, /value/). Typically, this list will
83 -- be expressed as a comprehension. An
84 -- association '(i, x)' defines the value of
85 -- the array at index 'i' to be 'x'.
86 -> Array i e
87 array = Array.array
88
89 -- SDM copied docs for (//) to remove GHC reference
90
91 -- | Constructs an array identical to the first argument except that it has
92 -- been updated by the associations in the right argument.
93 -- For example, if @m@ is a 1-origin, @n@ by @n@ matrix, then
94 --
95 -- > m//[((i,i), 0) | i <- [1..n]]
96 --
97 -- is the same matrix, except with the diagonal zeroed.
98 --
99 -- Repeated indices in the association list are handled as for 'array':
100 -- the resulting array is undefined (i.e. bottom),
101 (//) :: Ix i => Array i e -> [(i, e)] -> Array i e
102 (//) = (Array.//)
103
104 {- $code
105 > module Array (
106 > module Data.Ix, -- export all of Data.Ix
107 > Array, array, listArray, (!), bounds, indices, elems, assocs,
108 > accumArray, (//), accum, ixmap ) where
109 >
110 > import Data.Ix
111 > import Data.List( (\\) )
112 >
113 > infixl 9 !, //
114 >
115 > data (Ix a) => Array a b = MkArray (a,a) (a -> b) deriving ()
116 >
117 > array :: (Ix a) => (a,a) -> [(a,b)] -> Array a b
118 > array b ivs
119 > | any (not . inRange b. fst) ivs
120 > = error "Data.Array.array: out-of-range array association"
121 > | otherwise
122 > = MkArray b arr
123 > where
124 > arr j = case [ v | (i,v) <- ivs, i == j ] of
125 > [v] -> v
126 > [] -> error "Data.Array.!: undefined array element"
127 > _ -> error "Data.Array.!: multiply defined array element"
128 >
129 > listArray :: (Ix a) => (a,a) -> [b] -> Array a b
130 > listArray b vs = array b (zipWith (\ a b -> (a,b)) (range b) vs)
131 >
132 > (!) :: (Ix a) => Array a b -> a -> b
133 > (!) (MkArray _ f) = f
134 >
135 > bounds :: (Ix a) => Array a b -> (a,a)
136 > bounds (MkArray b _) = b
137 >
138 > indices :: (Ix a) => Array a b -> [a]
139 > indices = range . bounds
140 >
141 > elems :: (Ix a) => Array a b -> [b]
142 > elems a = [a!i | i <- indices a]
143 >
144 > assocs :: (Ix a) => Array a b -> [(a,b)]
145 > assocs a = [(i, a!i) | i <- indices a]
146 >
147 > (//) :: (Ix a) => Array a b -> [(a,b)] -> Array a b
148 > a // new_ivs = array (bounds a) (old_ivs ++ new_ivs)
149 > where
150 > old_ivs = [(i,a!i) | i <- indices a,
151 > i `notElem` new_is]
152 > new_is = [i | (i,_) <- new_ivs]
153 >
154 > accum :: (Ix a) => (b -> c -> b) -> Array a b -> [(a,c)]
155 > -> Array a b
156 > accum f = foldl (\a (i,v) -> a // [(i,f (a!i) v)])
157 >
158 > accumArray :: (Ix a) => (b -> c -> b) -> b -> (a,a) -> [(a,c)]
159 > -> Array a b
160 > accumArray f z b = accum f (array b [(i,z) | i <- range b])
161 >
162 > ixmap :: (Ix a, Ix b) => (a,a) -> (a -> b) -> Array b c
163 > -> Array a c
164 > ixmap b f a = array b [(i, a ! f i) | i <- range b]
165 >
166 > instance (Ix a) => Functor (Array a) where
167 > fmap fn (MkArray b f) = MkArray b (fn . f)
168 >
169 > instance (Ix a, Eq b) => Eq (Array a b) where
170 > a == a' = assocs a == assocs a'
171 >
172 > instance (Ix a, Ord b) => Ord (Array a b) where
173 > a <= a' = assocs a <= assocs a'
174 >
175 > instance (Ix a, Show a, Show b) => Show (Array a b) where
176 > showsPrec p a = showParen (p > arrPrec) (
177 > showString "array " .
178 > showsPrec (arrPrec+1) (bounds a) . showChar ' ' .
179 > showsPrec (arrPrec+1) (assocs a) )
180 >
181 > instance (Ix a, Read a, Read b) => Read (Array a b) where
182 > readsPrec p = readParen (p > arrPrec)
183 > (\r -> [ (array b as, u)
184 > | ("array",s) <- lex r,
185 > (b,t) <- readsPrec (arrPrec+1) s,
186 > (as,u) <- readsPrec (arrPrec+1) t ])
187 >
188 > -- Precedence of the 'array' function is that of application itself
189 > arrPrec = 10
190 -}