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