[project @ 2000-08-29 16:36:23 by simonpj]
[ghc-hetmet.git] / ghc / lib / std / Array.lhs
1 % -----------------------------------------------------------------------------
2 % $Id: Array.lhs,v 1.14 2000/08/29 16:36:23 simonpj 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
42 #ifndef __HUGS__
43 import Ix
44 import PrelList
45 import PrelArr          -- Most of the hard work is done here
46 import PrelBase
47 #else
48 import PrelPrim ( PrimArray
49                 , runST
50                 , primNewArray
51                 , primWriteArray
52                 , primReadArray
53                 , primUnsafeFreezeArray
54                 , primIndexArray
55                 )
56 import Ix
57 import List( (\\) )
58 #endif
59
60 infixl 9  !, //
61 \end{code}
62
63 #ifndef __HUGS__
64
65
66 %*********************************************************
67 %*                                                      *
68 \subsection{Definitions of array, !, bounds}
69 %*                                                      *
70 %*********************************************************
71
72 \begin{code}
73
74
75 {-# SPECIALISE listArray :: (Int,Int) -> [b] -> Array Int b #-}
76 listArray             :: (Ix a) => (a,a) -> [b] -> Array a b
77 listArray b vs        =  array b (zip (range b) vs)
78
79 {-# INLINE elems #-}
80 elems                 :: (Ix a) => Array a b -> [b]
81 elems a               =  [a!i | i <- indices a]
82
83 ixmap                 :: (Ix a, Ix b) => (a,a) -> (a -> b) -> Array b c -> Array a c
84 ixmap b f a           =  array b [(i, a ! f i) | i <- range b]
85 \end{code}
86
87
88 %*********************************************************
89 %*                                                      *
90 \subsection{Instance declarations for Array type}
91 %*                                                      *
92 %*********************************************************
93
94
95 #else
96 \begin{code}
97 data Array ix elt = Array (ix,ix) (PrimArray elt)
98
99 array :: Ix a => (a,a) -> [(a,b)] -> Array a b
100 array ixs@(ix_start, ix_end) ivs = runST (do
101   { mut_arr <- primNewArray (rangeSize ixs) arrEleBottom
102   ; mapM_ (\ (i,v) -> primWriteArray mut_arr (index ixs i) v) ivs 
103   ; arr <- primUnsafeFreezeArray mut_arr
104   ; return (Array ixs arr)
105   }
106   )
107  where
108   arrEleBottom = error "(Array.!): undefined array element"
109
110 listArray               :: Ix a => (a,a) -> [b] -> Array a b
111 listArray b vs          =  array b (zipWith (\ a b -> (a,b)) (range b) vs)
112
113 (!)                     :: Ix a => Array a b -> a -> b
114 (Array bounds arr) ! i  = primIndexArray arr (index bounds i)
115
116 bounds                  :: Ix a => Array a b -> (a,a)
117 bounds (Array b _)      =  b
118
119 indices           :: Ix a => Array a b -> [a]
120 indices           = range . bounds
121
122 elems             :: Ix a => Array a b -> [b]
123 elems a           =  [a!i | i <- indices a]
124
125 assocs            :: Ix a => Array a b -> [(a,b)]
126 assocs a          =  [(i, a!i) | i <- indices a]
127
128 (//)              :: Ix a => Array a b -> [(a,b)] -> Array a b
129 a // us           =  array (bounds a)
130                         ([(i,a!i) | i <- indices a \\ [i | (i,_) <- us]]
131                          ++ us)
132
133 accum             :: Ix a => (b -> c -> b) -> Array a b -> [(a,c)] -> Array a b
134 accum f           =  foldl (\a (i,v) -> a // [(i,f (a!i) v)])
135
136 accumArray        :: Ix a => (b -> c -> b) -> b -> (a,a) -> [(a,c)] -> Array a b
137 accumArray f z b  =  accum f (array b [(i,z) | i <- range b])
138
139 ixmap             :: (Ix a, Ix b) => (a,a) -> (a -> b) -> Array b c -> Array a c
140 ixmap b f a       =  array b [(i, a ! f i) | i <- range b]
141
142
143 instance (Ix a) => Functor (Array a) where
144     fmap f a = array (bounds a) [(i, f(a!i)) | i <- indices a]
145
146 instance (Ix a, Eq b) => Eq (Array a b) where
147     a == a'   =   assocs a == assocs a'
148
149 instance (Ix a, Ord b) => Ord (Array a b) where
150     a <= a'   =   assocs a <= assocs a'
151
152
153 instance  (Ix a, Show a, Show b) => Show (Array a b)  where
154     showsPrec p a = showParen (p > 9) (
155                     showString "array " .
156                     shows (bounds a) . showChar ' ' .
157                     shows (assocs a)                  )
158
159 instance  (Ix a, Read a, Read b) => Read (Array a b)  where
160     readsPrec p = readParen (p > 9)
161              (\r -> [(array b as, u) | ("array",s) <- lex r,
162                                        (b,t)       <- reads s,
163                                        (as,u)      <- reads t   ])
164
165 \end{code}
166 #endif