Array.hs

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

import Prelude
import Ix
import List( (\\) )

infixl 9  !, //

data (Ix a) => Array a b = MkArray (a,a) (a -> b)

--array       :: (Ix a) => (a,a) -> [(a,b)] -> Array a b
array b ivs =
    if and [inRange b i | (i,_) <- ivs]
        then MkArray b $
                     \j -> let vs = [v | (i,v) <- ivs, i == j]
                           in case vs of
                                [v]   -> v
                                []    -> error "Array.!: undefined array element"
                                _     -> error "Array.!: multiply defined array element"
                     
        else error "Array.array: out-of-range array association"

--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
(!) (MkArray _ f)     =  f

bounds                :: (Ix a) => Array a b -> (a,a)
bounds (MkArray 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 ix)         => Functor (Array ix) where
    fmap fn (MkArray b f) =  MkArray b (fn . f) 

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

instance  (Ix a,Ord 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  (Eq a,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   ])

Plain-text version of Array.hs | Valid HTML?