0 | module Data.HashMap.Array
3 | import Data.IOArray.Prims
5 | import Data.HashMap.Bits
10 | prim__newArray : Bits32 -> a -> PrimIO (ArrayData a)
11 | prim__newArray len x = Prims.prim__newArray (unsafeCast len) x
14 | prim__arrayGet : ArrayData a -> Bits32 -> PrimIO a
15 | prim__arrayGet arr i = Prims.prim__arrayGet arr (unsafeCast i)
18 | prim__arraySet : ArrayData a -> Bits32 -> a -> PrimIO ()
19 | prim__arraySet arr i x = Prims.prim__arraySet arr (unsafeCast i) x
22 | unsafeNewArray : Bits32 -> IO (ArrayData a)
23 | unsafeNewArray len = fromPrim $
prim__newArray len (believe_me ())
26 | unsafeInlinePerformIO : IO a -> a
27 | unsafeInlinePerformIO act =
28 | let MkIORes res %MkWorld = toPrim act %MkWorld
35 | (from : ArrayData a) ->
36 | (to : ArrayData b) ->
37 | (fromStart : Bits32) ->
38 | (toStart : Bits32) ->
39 | (fromStop : Bits32) ->
41 | copyFromArrayBy f from to fromStart toStart fromStop = case fromStart `prim__lt_Bits32` fromStop of
44 | val <- fromPrim $
prim__arrayGet from fromStart
45 | fromPrim $
prim__arraySet to toStart (f val)
46 | copyFromArrayBy f from to (assert_smaller fromStart $
unsafeIncr fromStart) (unsafeIncr toStart) fromStop
50 | (from : ArrayData a) ->
51 | (to : ArrayData a) ->
52 | (fromStart : Bits32) ->
53 | (toStart : Bits32) ->
54 | (fromStop : Bits32) ->
56 | copyFromArray from to fromStart toStart fromStop = case fromStart `prim__lt_Bits32` fromStop of
59 | val <- fromPrim $
prim__arrayGet from fromStart
60 | fromPrim $
prim__arraySet to toStart val
61 | copyFromArray from to (assert_smaller fromStart $
unsafeIncr fromStart) (unsafeIncr toStart) fromStop
64 | copyFromList : ArrayData a -> List a -> Bits32 -> IO ()
65 | copyFromList arr [] idx = pure ()
66 | copyFromList arr (x :: xs) idx = do
67 | fromPrim $
prim__arraySet arr idx x
68 | copyFromList arr xs (idx + 1)
71 | data Array : Type -> Type where
72 | MkArray : (len : Bits32) -> (arr : ArrayData a) -> Array a
78 | empty = MkArray 0 $
unsafeInlinePerformIO $
unsafeNewArray 0
81 | singleton : a -> Array a
82 | singleton x = unsafeInlinePerformIO $
do
83 | arr <- fromPrim $
Prims.prim__newArray 1 x
84 | pure $
MkArray 1 arr
87 | fromList : (xs : List a) -> Array a
89 | fromList (x :: xs) = unsafeInlinePerformIO $
do
90 | let len = 1 + cast (length xs)
91 | arr <- fromPrim $
prim__newArray len x
92 | copyFromList arr xs 1
93 | pure $
MkArray len arr
95 | toListOnto : Array a -> List a -> List a
96 | toListOnto (MkArray 0 _) acc = acc
97 | toListOnto xs@(MkArray len arr) acc =
98 | let last = unsafeInlinePerformIO $
fromPrim $
prim__arrayGet arr (len - 1)
101 | _ => toListOnto (assert_smaller xs $
MkArray (len - 1) arr) (last :: acc)
104 | length : Array a -> Bits32
105 | length (MkArray len x) = len
108 | unsafeIndex : Array a -> Bits32 -> a
109 | unsafeIndex (MkArray _ arr) idx = unsafeInlinePerformIO $
fromPrim $
prim__arrayGet arr idx
112 | index : Array a -> Bits32 -> Maybe a
114 | if 0 <= idx && idx < length arr
115 | then Just $
unsafeIndex arr idx
119 | update : Array a -> List (Bits32, a) -> Array a
120 | update arr [] = arr
121 | update (MkArray len arr) xs = unsafeInlinePerformIO $
do
122 | arr' <- unsafeNewArray len
123 | copyFromArray arr arr' 0 0 len
124 | updateFromList arr' xs len
125 | pure $
MkArray len arr'
128 | (arr : ArrayData a) ->
129 | (upds : List (Bits32, a)) ->
132 | updateFromList arr [] len = pure ()
133 | updateFromList arr ((idx, val) :: xs) len = do
134 | when (idx < len) $
fromPrim $
prim__arraySet arr idx val
135 | updateFromList arr xs len
138 | insert : (idx : Bits32) -> (val : a) -> Array a -> Array a
139 | insert idx val arr@(MkArray len orig) = if idx <= len
140 | then unsafeInlinePerformIO $
do
141 | new <- unsafeNewArray (len + 1)
142 | copyFromArray orig new 0 0 idx
143 | fromPrim $
prim__arraySet new idx val
144 | copyFromArray orig new idx (idx + 1) len
145 | pure $
MkArray (len + 1) new
149 | delete : (idx : Bits32) -> Array a -> Array a
150 | delete idx arr@(MkArray len orig) =
155 | else unsafeInlinePerformIO $
do
156 | new <- unsafeNewArray (len - 1)
158 | copyFromArray orig new 0 0 idx
160 | copyFromArray orig new (idx + 1) idx len
161 | pure $
MkArray (len - 1) new
164 | findIndex : (a -> Bool) -> Array a -> Maybe Bits32
165 | findIndex f arr = go 0 (length arr)
167 | go : Bits32 -> Bits32 -> Maybe Bits32
171 | else if f (unsafeIndex arr i)
173 | else go (assert_smaller i $
i + 1) len
176 | findWithIndex : (a -> Bool) -> Array a -> Maybe (Bits32, a)
177 | findWithIndex f arr = go 0 (length arr)
179 | go : Bits32 -> Bits32 -> Maybe (Bits32, a)
184 | let elem = unsafeIndex arr i
185 | in if f elem then Just (i, elem) else go (assert_smaller i $
i + 1) len
188 | append : (val : a) -> Array a -> Array a
189 | append val arr = insert (length arr) val arr
192 | Functor Array where
193 | map f (MkArray len arr) = MkArray len $
194 | unsafeInlinePerformIO $
do
195 | arr' <- unsafeNewArray len
196 | copyFromArrayBy f arr arr' 0 0 len
201 | (f : elem -> acc -> acc) ->
202 | acc -> Bits32 -> Array elem ->
204 | foldrImpl f z i arr = if i == 0
205 | then f (unsafeIndex arr i) z
207 | let elem = unsafeIndex arr i
208 | in foldrImpl f (f elem z) (assert_smaller i $
i - 1) arr
212 | (f : acc -> elem -> acc) ->
214 | (index : Bits32) ->
215 | (length : Bits32) ->
218 | foldlImpl f z i len arr = if i >= len
221 | let elem = unsafeIndex arr i
222 | in foldlImpl f z (assert_smaller i $
i + 1) len arr
225 | Foldable Array where
226 | foldr f z arr = foldrImpl f z (length arr - 1) arr
228 | foldl f z arr = foldlImpl f z 0 (length arr) arr
230 | null arr = length arr == 0
231 | toList arr = toListOnto arr []
232 | foldMap f arr = foldr (\elem, acc => f elem <+> acc) neutral arr
235 | Show a => Show (Array a) where
236 | show = show . toList
238 | parameters (pred : a -> b -> Bool)
239 | allFrom : Bits32 -> Array a -> Array b -> Bool
240 | allFrom idx arr1 arr2 = if length arr1 <= idx || length arr2 <= idx
243 | let x = index arr1 idx
245 | in fromMaybe False [| pred x y |]
246 | && allFrom (assert_smaller idx $
idx + 1) arr1 arr2
249 | all : Array a -> Array b -> Bool
253 | Eq a => Eq (Array a) where
254 | x == y = length x == length y && all (==) x y