summaryrefslogtreecommitdiff
path: root/ghc/interpreter/lib/Array.hs
blob: a3e9d420879905726289b9fe40a52f13e4f5e341 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
-----------------------------------------------------------------------------
-- Standard Library: Array operations
--
-- Suitable for use with Hugs 98
-----------------------------------------------------------------------------

module  Array ( 
    module Ix,  -- export all of Ix 
    Array, array, listArray, (!), bounds, indices, elems, assocs, 
    accumArray, (//), accum, ixmap ) where

import Ix
import List( (\\) )

infixl 9  !, //

data Array ix elt = Array (ix,ix) (PrimArray elt)

array :: Ix a => (a,a) -> [(a,b)] -> Array a b
array ixs@(ix_start, ix_end) ivs = runST (do
  { mut_arr <- primNewArray (rangeSize ixs) arrEleBottom
  ; mapM_ (\ (i,v) -> primWriteArray mut_arr (index ixs i) v) ivs 
  ; arr <- primUnsafeFreezeArray mut_arr
  ; return (Array ixs arr)
  }
  )
 where
  arrEleBottom = error "(Array.!): undefined array element"

listArray               :: Ix a => (a,a) -> [b] -> Array a b
listArray b vs          =  array b (zipWith (\ a b -> (a,b)) (range b) vs)

(!)	                :: Ix a => Array a b -> a -> b
(Array bounds arr) ! i  = primIndexArray arr (index bounds i)

bounds                  :: Ix a => Array a b -> (a,a)
bounds (Array b _)      =  b

indices           :: Ix a => Array a b -> [a]
indices	          = range . bounds

elems             :: Ix a => Array a b -> [b]
elems a           =  [a!i | i <- indices a]

assocs	          :: Ix a => Array a b -> [(a,b)]
assocs a          =  [(i, a!i) | i <- indices a]

(//)              :: Ix a => Array a b -> [(a,b)] -> Array a b
a // us           =  array (bounds a)
                        ([(i,a!i) | i <- indices a \\ [i | (i,_) <- us]]
                         ++ us)

accum             :: Ix a => (b -> c -> b) -> Array a b -> [(a,c)] -> Array a b
accum f           =  foldl (\a (i,v) -> a // [(i,f (a!i) v)])

accumArray        :: Ix a => (b -> c -> b) -> b -> (a,a) -> [(a,c)] -> Array a b
accumArray f z b  =  accum f (array b [(i,z) | i <- range b])

ixmap	          :: (Ix a, Ix b) => (a,a) -> (a -> b) -> Array b c -> Array a c
ixmap b f a       =  array b [(i, a ! f i) | i <- range b]


instance (Ix a) => Functor (Array a) where
    fmap f a = array (bounds a) [(i, f(a!i)) | i <- indices a]

instance (Ix a, Eq b) => Eq (Array a b) where
    a == a'   =   assocs a == assocs a'

instance (Ix a, Ord b) => Ord (Array a b) where
    a <= a'   =   assocs a <= assocs a'


instance  (Ix a, Show a, Show b) => Show (Array a b)  where
    showsPrec p a = showParen (p > 9) (
		    showString "array " .
		    shows (bounds a) . showChar ' ' .
		    shows (assocs a)                  )

instance  (Ix a, Read a, Read b) => Read (Array a b)  where
    readsPrec p = readParen (p > 9)
	     (\r -> [(array b as, u) | ("array",s) <- lex r,
				       (b,t)       <- reads s,
				       (as,u)      <- reads t   ])

-----------------------------------------------------------------------------