vnew -> basicNew
[darcs-mirrors/vector.git] / Data / Vector / Primitive.hs
1 {-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-}
2
3 -- |
4 -- Module : Data.Vector.Primitive
5 -- Copyright : (c) Roman Leshchinskiy 2008-2009
6 -- License : BSD-style
7 --
8 -- Maintainer : Roman Leshchinskiy <rl@cse.unsw.edu.au>
9 -- Stability : experimental
10 -- Portability : non-portable
11 --
12 -- Unboxed vectors of primitive types.
13 --
14
15 module Data.Vector.Primitive (
16 Vector, MVector(..), Prim,
17
18 -- * Length information
19 length, null,
20
21 -- * Construction
22 empty, singleton, cons, snoc, replicate, (++), copy,
23
24 -- * Accessing individual elements
25 (!), head, last,
26
27 -- * Subvectors
28 slice, init, tail, take, drop,
29
30 -- * Permutations
31 accum, (//), backpermute, reverse,
32
33 -- * Mapping
34 map, concatMap,
35
36 -- * Zipping and unzipping
37 zipWith, zipWith3,
38
39 -- * Filtering
40 filter, takeWhile, dropWhile,
41
42 -- * Searching
43 elem, notElem, find, findIndex,
44
45 -- * Folding
46 foldl, foldl1, foldl', foldl1', foldr, foldr1,
47
48 -- * Specialised folds
49 sum, product, maximum, minimum,
50
51 -- * Unfolding
52 unfoldr,
53
54 -- * Scans
55 prescanl, prescanl',
56 postscanl, postscanl',
57 scanl, scanl', scanl1, scanl1',
58
59 -- * Enumeration
60 enumFromTo, enumFromThenTo,
61
62 -- * Conversion to/from lists
63 toList, fromList
64 ) where
65
66 import qualified Data.Vector.Generic as G
67 import Data.Vector.Primitive.Mutable ( MVector(..) )
68 import Data.Primitive.ByteArray
69 import Data.Primitive ( Prim )
70
71 import Control.Monad.ST ( runST )
72
73 import Prelude hiding ( length, null,
74 replicate, (++),
75 head, last,
76 init, tail, take, drop, reverse,
77 map, concatMap,
78 zipWith, zipWith3, zip, zip3, unzip, unzip3,
79 filter, takeWhile, dropWhile,
80 elem, notElem,
81 foldl, foldl1, foldr, foldr1,
82 sum, product, minimum, maximum,
83 scanl, scanl1,
84 enumFromTo, enumFromThenTo )
85
86 import qualified Prelude
87
88 -- | Unboxed vectors of primitive types
89 data Vector a = Vector {-# UNPACK #-} !Int
90 {-# UNPACK #-} !Int
91 {-# UNPACK #-} !ByteArray
92
93 instance (Show a, Prim a) => Show (Vector a) where
94 show = (Prelude.++ " :: Data.Vector.Primitive.Vector") . ("fromList " Prelude.++) . show . toList
95
96 instance Prim a => G.Vector Vector a where
97 {-# INLINE basicNew #-}
98 basicNew init = runST (do
99 MVector i n marr <- init
100 arr <- unsafeFreezeByteArray marr
101 return (Vector i n arr))
102
103 {-# INLINE vlength #-}
104 vlength (Vector _ n _) = n
105
106 {-# INLINE unsafeSlice #-}
107 unsafeSlice (Vector i _ arr) j n = Vector (i+j) n arr
108
109 {-# INLINE unsafeIndexM #-}
110 unsafeIndexM (Vector i _ arr) j = return (indexByteArray arr (i+j))
111
112 instance (Prim a, Eq a) => Eq (Vector a) where
113 {-# INLINE (==) #-}
114 (==) = G.eq
115
116 instance (Prim a, Ord a) => Ord (Vector a) where
117 {-# INLINE compare #-}
118 compare = G.cmp
119
120 -- Length
121 -- ------
122
123 length :: Prim a => Vector a -> Int
124 {-# INLINE length #-}
125 length = G.length
126
127 null :: Prim a => Vector a -> Bool
128 {-# INLINE null #-}
129 null = G.null
130
131 -- Construction
132 -- ------------
133
134 -- | Empty vector
135 empty :: Prim a => Vector a
136 {-# INLINE empty #-}
137 empty = G.empty
138
139 -- | Vector with exaclty one element
140 singleton :: Prim a => a -> Vector a
141 {-# INLINE singleton #-}
142 singleton = G.singleton
143
144 -- | Vector of the given length with the given value in each position
145 replicate :: Prim a => Int -> a -> Vector a
146 {-# INLINE replicate #-}
147 replicate = G.replicate
148
149 -- | Prepend an element
150 cons :: Prim a => a -> Vector a -> Vector a
151 {-# INLINE cons #-}
152 cons = G.cons
153
154 -- | Append an element
155 snoc :: Prim a => Vector a -> a -> Vector a
156 {-# INLINE snoc #-}
157 snoc = G.snoc
158
159 infixr 5 ++
160 -- | Concatenate two vectors
161 (++) :: Prim a => Vector a -> Vector a -> Vector a
162 {-# INLINE (++) #-}
163 (++) = (G.++)
164
165 -- | Create a copy of a vector. Useful when dealing with slices.
166 copy :: Prim a => Vector a -> Vector a
167 {-# INLINE copy #-}
168 copy = G.copy
169
170 -- Accessing individual elements
171 -- -----------------------------
172
173 -- | Indexing
174 (!) :: Prim a => Vector a -> Int -> a
175 {-# INLINE (!) #-}
176 (!) = (G.!)
177
178 -- | First element
179 head :: Prim a => Vector a -> a
180 {-# INLINE head #-}
181 head = G.head
182
183 -- | Last element
184 last :: Prim a => Vector a -> a
185 {-# INLINE last #-}
186 last = G.last
187
188 -- Subarrays
189 -- ---------
190
191 -- | Yield a part of the vector without copying it. Safer version of
192 -- 'unsafeSlice'.
193 slice :: Prim a => Vector a -> Int -- ^ starting index
194 -> Int -- ^ length
195 -> Vector a
196 {-# INLINE slice #-}
197 slice = G.slice
198
199 -- | Yield all but the last element without copying.
200 init :: Prim a => Vector a -> Vector a
201 {-# INLINE init #-}
202 init = G.init
203
204 -- | All but the first element (without copying).
205 tail :: Prim a => Vector a -> Vector a
206 {-# INLINE tail #-}
207 tail = G.tail
208
209 -- | Yield the first @n@ elements without copying.
210 take :: Prim a => Int -> Vector a -> Vector a
211 {-# INLINE take #-}
212 take = G.take
213
214 -- | Yield all but the first @n@ elements without copying.
215 drop :: Prim a => Int -> Vector a -> Vector a
216 {-# INLINE drop #-}
217 drop = G.drop
218
219 -- Permutations
220 -- ------------
221
222 accum :: Prim a => (a -> b -> a) -> Vector a -> [(Int,b)] -> Vector a
223 {-# INLINE accum #-}
224 accum = G.accum
225
226 (//) :: Prim a => Vector a -> [(Int, a)] -> Vector a
227 {-# INLINE (//) #-}
228 (//) = (G.//)
229
230 backpermute :: Prim a => Vector a -> Vector Int -> Vector a
231 {-# INLINE backpermute #-}
232 backpermute = G.backpermute
233
234 reverse :: Prim a => Vector a -> Vector a
235 {-# INLINE reverse #-}
236 reverse = G.reverse
237
238 -- Mapping
239 -- -------
240
241 -- | Map a function over a vector
242 map :: (Prim a, Prim b) => (a -> b) -> Vector a -> Vector b
243 {-# INLINE map #-}
244 map = G.map
245
246 concatMap :: (Prim a, Prim b) => (a -> Vector b) -> Vector a -> Vector b
247 {-# INLINE concatMap #-}
248 concatMap = G.concatMap
249
250 -- Zipping/unzipping
251 -- -----------------
252
253 -- | Zip two vectors with the given function.
254 zipWith :: (Prim a, Prim b, Prim c)
255 => (a -> b -> c) -> Vector a -> Vector b -> Vector c
256 {-# INLINE zipWith #-}
257 zipWith = G.zipWith
258
259 -- | Zip three vectors with the given function.
260 zipWith3 :: (Prim a, Prim b, Prim c, Prim d)
261 => (a -> b -> c -> d) -> Vector a -> Vector b -> Vector c -> Vector d
262 {-# INLINE zipWith3 #-}
263 zipWith3 = G.zipWith3
264
265 -- Filtering
266 -- ---------
267
268 -- | Drop elements which do not satisfy the predicate
269 filter :: Prim a => (a -> Bool) -> Vector a -> Vector a
270 {-# INLINE filter #-}
271 filter = G.filter
272
273 -- | Yield the longest prefix of elements satisfying the predicate.
274 takeWhile :: Prim a => (a -> Bool) -> Vector a -> Vector a
275 {-# INLINE takeWhile #-}
276 takeWhile = G.takeWhile
277
278 -- | Drop the longest prefix of elements that satisfy the predicate.
279 dropWhile :: Prim a => (a -> Bool) -> Vector a -> Vector a
280 {-# INLINE dropWhile #-}
281 dropWhile = G.dropWhile
282
283 -- Searching
284 -- ---------
285
286 infix 4 `elem`
287 -- | Check whether the vector contains an element
288 elem :: (Prim a, Eq a) => a -> Vector a -> Bool
289 {-# INLINE elem #-}
290 elem = G.elem
291
292 infix 4 `notElem`
293 -- | Inverse of `elem`
294 notElem :: (Prim a, Eq a) => a -> Vector a -> Bool
295 {-# INLINE notElem #-}
296 notElem = G.notElem
297
298 -- | Yield 'Just' the first element matching the predicate or 'Nothing' if no
299 -- such element exists.
300 find :: Prim a => (a -> Bool) -> Vector a -> Maybe a
301 {-# INLINE find #-}
302 find = G.find
303
304 -- | Yield 'Just' the index of the first element matching the predicate or
305 -- 'Nothing' if no such element exists.
306 findIndex :: Prim a => (a -> Bool) -> Vector a -> Maybe Int
307 {-# INLINE findIndex #-}
308 findIndex = G.findIndex
309
310 -- Folding
311 -- -------
312
313 -- | Left fold
314 foldl :: Prim b => (a -> b -> a) -> a -> Vector b -> a
315 {-# INLINE foldl #-}
316 foldl = G.foldl
317
318 -- | Lefgt fold on non-empty vectors
319 foldl1 :: Prim a => (a -> a -> a) -> Vector a -> a
320 {-# INLINE foldl1 #-}
321 foldl1 = G.foldl1
322
323 -- | Left fold with strict accumulator
324 foldl' :: Prim b => (a -> b -> a) -> a -> Vector b -> a
325 {-# INLINE foldl' #-}
326 foldl' = G.foldl'
327
328 -- | Left fold on non-empty vectors with strict accumulator
329 foldl1' :: Prim a => (a -> a -> a) -> Vector a -> a
330 {-# INLINE foldl1' #-}
331 foldl1' = G.foldl1'
332
333 -- | Right fold
334 foldr :: Prim a => (a -> b -> b) -> b -> Vector a -> b
335 {-# INLINE foldr #-}
336 foldr = G.foldr
337
338 -- | Right fold on non-empty vectors
339 foldr1 :: Prim a => (a -> a -> a) -> Vector a -> a
340 {-# INLINE foldr1 #-}
341 foldr1 = G.foldr1
342
343 -- Specialised folds
344 -- -----------------
345
346 sum :: (Prim a, Num a) => Vector a -> a
347 {-# INLINE sum #-}
348 sum = G.sum
349
350 product :: (Prim a, Num a) => Vector a -> a
351 {-# INLINE product #-}
352 product = G.product
353
354 maximum :: (Prim a, Ord a) => Vector a -> a
355 {-# INLINE maximum #-}
356 maximum = G.maximum
357
358 minimum :: (Prim a, Ord a) => Vector a -> a
359 {-# INLINE minimum #-}
360 minimum = G.minimum
361
362 -- Unfolding
363 -- ---------
364
365 unfoldr :: Prim a => (b -> Maybe (a, b)) -> b -> Vector a
366 {-# INLINE unfoldr #-}
367 unfoldr = G.unfoldr
368
369 -- Scans
370 -- -----
371
372 -- | Prefix scan
373 prescanl :: (Prim a, Prim b) => (a -> b -> a) -> a -> Vector b -> Vector a
374 {-# INLINE prescanl #-}
375 prescanl = G.prescanl
376
377 -- | Prefix scan with strict accumulator
378 prescanl' :: (Prim a, Prim b) => (a -> b -> a) -> a -> Vector b -> Vector a
379 {-# INLINE prescanl' #-}
380 prescanl' = G.prescanl'
381
382 -- | Suffix scan
383 postscanl :: (Prim a, Prim b) => (a -> b -> a) -> a -> Vector b -> Vector a
384 {-# INLINE postscanl #-}
385 postscanl = G.postscanl
386
387 -- | Suffix scan with strict accumulator
388 postscanl' :: (Prim a, Prim b) => (a -> b -> a) -> a -> Vector b -> Vector a
389 {-# INLINE postscanl' #-}
390 postscanl' = G.postscanl'
391
392 -- | Haskell-style scan
393 scanl :: (Prim a, Prim b) => (a -> b -> a) -> a -> Vector b -> Vector a
394 {-# INLINE scanl #-}
395 scanl = G.scanl
396
397 -- | Haskell-style scan with strict accumulator
398 scanl' :: (Prim a, Prim b) => (a -> b -> a) -> a -> Vector b -> Vector a
399 {-# INLINE scanl' #-}
400 scanl' = G.scanl'
401
402 -- | Scan over a non-empty 'Vector'
403 scanl1 :: Prim a => (a -> a -> a) -> Vector a -> Vector a
404 {-# INLINE scanl1 #-}
405 scanl1 = G.scanl1
406
407 -- | Scan over a non-empty 'Vector' with a strict accumulator
408 scanl1' :: Prim a => (a -> a -> a) -> Vector a -> Vector a
409 {-# INLINE scanl1' #-}
410 scanl1' = G.scanl1'
411
412 -- Enumeration
413 -- -----------
414
415 enumFromTo :: (Prim a, Enum a) => a -> a -> Vector a
416 {-# INLINE enumFromTo #-}
417 enumFromTo = G.enumFromTo
418
419 enumFromThenTo :: (Prim a, Enum a) => a -> a -> a -> Vector a
420 {-# INLINE enumFromThenTo #-}
421 enumFromThenTo = G.enumFromThenTo
422
423 -- Conversion to/from lists
424 -- ------------------------
425
426 -- | Convert a vector to a list
427 toList :: Prim a => Vector a -> [a]
428 {-# INLINE toList #-}
429 toList = G.toList
430
431 -- | Convert a list to a vector
432 fromList :: Prim a => [a] -> Vector a
433 {-# INLINE fromList #-}
434 fromList = G.fromList
435