Add unsafeIndex and unsafeSlice
[darcs-mirrors/vector.git] / Data / Vector / Generic.hs
1 {-# LANGUAGE Rank2Types, MultiParamTypeClasses, FlexibleContexts,
2 ScopedTypeVariables #-}
3 -- |
4 -- Module : Data.Vector.Generic
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 -- Generic interface to pure vectors
13 --
14
15 #include "phases.h"
16
17 module Data.Vector.Generic (
18 -- * Immutable vectors
19 Vector(..),
20
21 -- * Length information
22 length, null,
23
24 -- * Construction
25 empty, singleton, cons, snoc, replicate, (++), copy,
26
27 -- * Accessing individual elements
28 (!), head, last, indexM, headM, lastM,
29 unsafeIndex, unsafeIndexM,
30
31 -- * Subvectors
32 slice, init, tail, take, drop,
33 unsafeSlice,
34
35 -- * Permutations
36 accum, (//), update, backpermute, reverse,
37
38 -- * Mapping
39 map, concatMap,
40
41 -- * Zipping and unzipping
42 zipWith, zipWith3, zip, zip3, unzip, unzip3,
43
44 -- * Comparisons
45 eq, cmp,
46
47 -- * Filtering
48 filter, takeWhile, dropWhile,
49
50 -- * Searching
51 elem, notElem, find, findIndex,
52
53 -- * Folding
54 foldl, foldl1, foldl', foldl1', foldr, foldr1,
55
56 -- * Specialised folds
57 and, or, sum, product, maximum, minimum,
58
59 -- * Unfolding
60 unfoldr,
61
62 -- * Scans
63 prescanl, prescanl',
64 postscanl, postscanl',
65 scanl, scanl', scanl1, scanl1',
66
67 -- * Enumeration
68 enumFromTo, enumFromThenTo,
69
70 -- * Conversion to/from lists
71 toList, fromList,
72
73 -- * Conversion to/from Streams
74 stream, unstream,
75
76 -- * MVector-based initialisation
77 new
78 ) where
79
80 import Data.Vector.Generic.Mutable ( MVector )
81
82 import qualified Data.Vector.Generic.New as New
83 import Data.Vector.Generic.New ( New )
84
85 import qualified Data.Vector.Fusion.Stream as Stream
86 import Data.Vector.Fusion.Stream ( Stream, MStream, inplace, inplace' )
87 import qualified Data.Vector.Fusion.Stream.Monadic as MStream
88 import Data.Vector.Fusion.Stream.Size
89 import Data.Vector.Fusion.Util
90
91 import Control.Exception ( assert )
92
93 import Prelude hiding ( length, null,
94 replicate, (++),
95 head, last,
96 init, tail, take, drop, reverse,
97 map, concatMap,
98 zipWith, zipWith3, zip, zip3, unzip, unzip3,
99 filter, takeWhile, dropWhile,
100 elem, notElem,
101 foldl, foldl1, foldr, foldr1,
102 and, or, sum, product, maximum, minimum,
103 scanl, scanl1,
104 enumFromTo, enumFromThenTo )
105
106 -- | Class of immutable vectors.
107 --
108 class Vector v a where
109 -- | Construct a pure vector from a monadic initialiser (not fusible!)
110 basicNew :: (forall mv m. MVector mv m a => m (mv a)) -> v a
111
112 -- | Length of the vector (not fusible!)
113 basicLength :: v a -> Int
114
115 -- | Yield a part of the vector without copying it. No range checks!
116 basicUnsafeSlice :: v a -> Int -> Int -> v a
117
118 -- | Yield the element at the given position in a monad. The monad allows us
119 -- to be strict in the vector if we want. Suppose we had
120 --
121 -- > unsafeIndex :: v a -> Int -> a
122 --
123 -- instead. Now, if we wanted to copy a vector, we'd do something like
124 --
125 -- > copy mv v ... = ... unsafeWrite mv i (unsafeIndex v i) ...
126 --
127 -- For lazy vectors, the indexing would not be evaluated which means that we
128 -- would retain a reference to the original vector in each element we write.
129 -- This is not what we want!
130 --
131 -- With 'basicUnsafeIndexM', we can do
132 --
133 -- > copy mv v ... = ... case basicUnsafeIndexM v i of
134 -- > Box x -> unsafeWrite mv i x ...
135 --
136 -- which does not have this problem because indexing (but not the returned
137 -- element!) is evaluated immediately.
138 --
139 basicUnsafeIndexM :: Monad m => v a -> Int -> m a
140
141 -- Fusion
142 -- ------
143
144 -- | Construct a pure vector from a monadic initialiser
145 new :: Vector v a => New a -> v a
146 {-# INLINE new #-}
147 new m = new' undefined m
148
149 -- | Same as 'new' but with a dummy argument necessary for correctly typing
150 -- the rule @uninplace@.
151 --
152 -- See http://hackage.haskell.org/trac/ghc/ticket/2600
153 new' :: Vector v a => v a -> New a -> v a
154 {-# INLINE_STREAM new' #-}
155 new' _ m = basicNew (New.run m)
156
157 -- | Convert a vector to a 'Stream'
158 stream :: Vector v a => v a -> Stream a
159 {-# INLINE_STREAM stream #-}
160 stream v = v `seq` (Stream.unfoldr get 0 `Stream.sized` Exact n)
161 where
162 n = length v
163
164 -- NOTE: the False case comes first in Core so making it the recursive one
165 -- makes the code easier to read
166 {-# INLINE get #-}
167 get i | i >= n = Nothing
168 | otherwise = case basicUnsafeIndexM v i of Box x -> Just (x, i+1)
169
170 -- | Create a vector from a 'Stream'
171 unstream :: Vector v a => Stream a -> v a
172 {-# INLINE unstream #-}
173 unstream s = new (New.unstream s)
174
175 {-# RULES
176
177 "stream/unstream [Vector]" forall v s.
178 stream (new' v (New.unstream s)) = s
179
180 "New.unstream/stream/new [Vector]" forall v p.
181 New.unstream (stream (new' v p)) = p
182
183 #-}
184
185 {-# RULES
186
187 "inplace [Vector]"
188 forall (f :: forall m. Monad m => MStream m a -> MStream m a) v m.
189 New.unstream (inplace f (stream (new' v m))) = New.transform f m
190
191 "uninplace [Vector]"
192 forall (f :: forall m. Monad m => MStream m a -> MStream m a) v m.
193 stream (new' v (New.transform f m)) = inplace f (stream (new' v m))
194
195 #-}
196
197 -- Length
198 -- ------
199
200 length :: Vector v a => v a -> Int
201 {-# INLINE_STREAM length #-}
202 length v = basicLength v
203
204 {-# RULES
205
206 "length/unstream [Vector]" forall v s.
207 length (new' v (New.unstream s)) = Stream.length s
208
209 #-}
210
211 null :: Vector v a => v a -> Bool
212 {-# INLINE null #-}
213 null v = length v == 0
214
215 -- Construction
216 -- ------------
217
218 -- | Empty vector
219 empty :: Vector v a => v a
220 {-# INLINE empty #-}
221 empty = unstream Stream.empty
222
223 -- | Vector with exaclty one element
224 singleton :: Vector v a => a -> v a
225 {-# INLINE singleton #-}
226 singleton x = unstream (Stream.singleton x)
227
228 -- | Vector of the given length with the given value in each position
229 replicate :: Vector v a => Int -> a -> v a
230 {-# INLINE replicate #-}
231 replicate n = unstream . Stream.replicate n
232
233 -- | Prepend an element
234 cons :: Vector v a => a -> v a -> v a
235 {-# INLINE cons #-}
236 cons x = unstream . Stream.cons x . stream
237
238 -- | Append an element
239 snoc :: Vector v a => v a -> a -> v a
240 {-# INLINE snoc #-}
241 snoc v = unstream . Stream.snoc (stream v)
242
243 infixr 5 ++
244 -- | Concatenate two vectors
245 (++) :: Vector v a => v a -> v a -> v a
246 {-# INLINE (++) #-}
247 v ++ w = unstream (stream v Stream.++ stream w)
248
249 -- | Create a copy of a vector. Useful when dealing with slices.
250 copy :: Vector v a => v a -> v a
251 {-# INLINE_STREAM copy #-}
252 copy = unstream . stream
253
254 {-# RULES
255
256 "copy/unstream [Vector]" forall v s.
257 copy (new' v (New.unstream s)) = new' v (New.unstream s)
258
259 #-}
260
261 -- Accessing individual elements
262 -- -----------------------------
263
264 -- | Indexing
265 (!) :: Vector v a => v a -> Int -> a
266 {-# INLINE_STREAM (!) #-}
267 v ! i = assert (i >= 0 && i < length v)
268 $ unId (basicUnsafeIndexM v i)
269
270 -- | Unsafe indexing without bounds checking
271 unsafeIndex :: Vector v a => v a -> Int -> a
272 {-# INLINE_STREAM unsafeIndex #-}
273 unsafeIndex v i = unId (basicUnsafeIndexM v i)
274
275 -- | First element
276 head :: Vector v a => v a -> a
277 {-# INLINE_STREAM head #-}
278 head v = v ! 0
279
280 -- | Last element
281 last :: Vector v a => v a -> a
282 {-# INLINE_STREAM last #-}
283 last v = v ! (length v - 1)
284
285 {-# RULES
286
287 "(!)/unstream [Vector]" forall v i s.
288 new' v (New.unstream s) ! i = s Stream.!! i
289
290 "unsafeIndex/unstream [Vector]" forall v i s.
291 unsafeIndex (new' v (New.unstream s)) i = s Stream.!! i
292
293 "head/unstream [Vector]" forall v s.
294 head (new' v (New.unstream s)) = Stream.head s
295
296 "last/unstream [Vector]" forall v s.
297 last (new' v (New.unstream s)) = Stream.last s
298
299 #-}
300
301 -- | Monadic indexing which can be strict in the vector while remaining lazy in
302 -- the element.
303 indexM :: (Vector v a, Monad m) => v a -> Int -> m a
304 {-# INLINE_STREAM indexM #-}
305 indexM v i = assert (i >= 0 && i < length v)
306 $ basicUnsafeIndexM v i
307
308 -- | Unsafe monadic indexing without bounds checks
309 unsafeIndexM :: (Vector v a, Monad m) => v a -> Int -> m a
310 {-# INLINE_STREAM unsafeIndexM #-}
311 unsafeIndexM v i = basicUnsafeIndexM v i
312
313 headM :: (Vector v a, Monad m) => v a -> m a
314 {-# INLINE_STREAM headM #-}
315 headM v = indexM v 0
316
317 lastM :: (Vector v a, Monad m) => v a -> m a
318 {-# INLINE_STREAM lastM #-}
319 lastM v = indexM v (length v - 1)
320
321 -- FIXME: the rhs of these rules are lazy in the stream which is WRONG
322 {- RULES
323
324 "indexM/unstream [Vector]" forall v i s.
325 indexM (new' v (New.unstream s)) i = return (s Stream.!! i)
326
327 "headM/unstream [Vector]" forall v s.
328 headM (new' v (New.unstream s)) = return (Stream.head s)
329
330 "lastM/unstream [Vector]" forall v s.
331 lastM (new' v (New.unstream s)) = return (Stream.last s)
332
333 -}
334
335 -- Subarrays
336 -- ---------
337
338 -- FIXME: slicing doesn't work with the inplace stuff at the moment
339
340 -- | Yield a part of the vector without copying it.
341 slice :: Vector v a => v a -> Int -- ^ starting index
342 -> Int -- ^ length
343 -> v a
344 {-# INLINE_STREAM slice #-}
345 slice v i n = assert (i >= 0 && n >= 0 && i+n <= length v)
346 $ basicUnsafeSlice v i n
347
348 -- | Unsafely yield a part of the vector without copying it and without
349 -- performing bounds checks.
350 unsafeSlice :: Vector v a => v a -> Int -- ^ starting index
351 -> Int -- ^ length
352 -> v a
353 {-# INLINE_STREAM unsafeSlice #-}
354 unsafeSlice v i n = basicUnsafeSlice v i n
355
356 -- | Yield all but the last element without copying.
357 init :: Vector v a => v a -> v a
358 {-# INLINE_STREAM init #-}
359 init v = slice v 0 (length v - 1)
360
361 -- | All but the first element (without copying).
362 tail :: Vector v a => v a -> v a
363 {-# INLINE_STREAM tail #-}
364 tail v = slice v 1 (length v - 1)
365
366 -- | Yield the first @n@ elements without copying.
367 take :: Vector v a => Int -> v a -> v a
368 {-# INLINE_STREAM take #-}
369 take n v = slice v 0 (min n' (length v))
370 where n' = max n 0
371
372 -- | Yield all but the first @n@ elements without copying.
373 drop :: Vector v a => Int -> v a -> v a
374 {-# INLINE_STREAM drop #-}
375 drop n v = slice v (min n' len) (max 0 (len - n'))
376 where n' = max n 0
377 len = length v
378
379 {-# RULES
380
381 "slice/new [Vector]" forall v p i n.
382 slice (new' v p) i n = new' v (New.slice p i n)
383
384 "unsafeSlice/new [Vector]" forall v p i n.
385 unsafeSlice (new' v p) i n = new' v (New.unsafeSlice p i n)
386
387 "init/new [Vector]" forall v p.
388 init (new' v p) = new' v (New.init p)
389
390 "tail/new [Vector]" forall v p.
391 tail (new' v p) = new' v (New.tail p)
392
393 "take/new [Vector]" forall n v p.
394 take n (new' v p) = new' v (New.take n p)
395
396 "drop/new [Vector]" forall n v p.
397 drop n (new' v p) = new' v (New.drop n p)
398
399 #-}
400
401 -- Permutations
402 -- ------------
403
404 accum :: Vector v a => (a -> b -> a) -> v a -> [(Int,b)] -> v a
405 {-# INLINE accum #-}
406 accum f v us = new (New.accum f (New.unstream (stream v))
407 (Stream.fromList us))
408
409 (//) :: Vector v a => v a -> [(Int, a)] -> v a
410 {-# INLINE (//) #-}
411 v // us = new (New.update (New.unstream (stream v))
412 (Stream.fromList us))
413
414 update :: (Vector v a, Vector v (Int, a)) => v a -> v (Int, a) -> v a
415 {-# INLINE update #-}
416 update v w = new (New.update (New.unstream (stream v)) (stream w))
417
418 -- This somewhat non-intuitive definition ensures that the resulting vector
419 -- does not retain references to the original one even if it is lazy in its
420 -- elements. This would not be the case if we simply used
421 --
422 -- backpermute v is = map (v!) is
423 backpermute :: (Vector v a, Vector v Int) => v a -> v Int -> v a
424 {-# INLINE backpermute #-}
425 backpermute v is = seq v
426 $ unstream
427 $ Stream.unbox
428 $ Stream.map (indexM v)
429 $ stream is
430
431 reverse :: (Vector v a) => v a -> v a
432 {-# INLINE reverse #-}
433 reverse = new . New.reverse . New.unstream . stream
434
435 -- Mapping
436 -- -------
437
438 -- | Map a function over a vector
439 map :: (Vector v a, Vector v b) => (a -> b) -> v a -> v b
440 {-# INLINE map #-}
441 map f = unstream . inplace' (MStream.map f) . stream
442
443 concatMap :: (Vector v a, Vector v b) => (a -> v b) -> v a -> v b
444 {-# INLINE concatMap #-}
445 concatMap f = unstream . Stream.concatMap (stream . f) . stream
446
447 -- Zipping/unzipping
448 -- -----------------
449
450 -- | Zip two vectors with the given function.
451 zipWith :: (Vector v a, Vector v b, Vector v c) => (a -> b -> c) -> v a -> v b -> v c
452 {-# INLINE zipWith #-}
453 zipWith f xs ys = unstream (Stream.zipWith f (stream xs) (stream ys))
454
455 -- | Zip three vectors with the given function.
456 zipWith3 :: (Vector v a, Vector v b, Vector v c, Vector v d) => (a -> b -> c -> d) -> v a -> v b -> v c -> v d
457 {-# INLINE zipWith3 #-}
458 zipWith3 f xs ys zs = unstream (Stream.zipWith3 f (stream xs) (stream ys) (stream zs))
459
460 zip :: (Vector v a, Vector v b, Vector v (a,b)) => v a -> v b -> v (a, b)
461 {-# INLINE zip #-}
462 zip = zipWith (,)
463
464 zip3 :: (Vector v a, Vector v b, Vector v c, Vector v (a, b, c)) => v a -> v b -> v c -> v (a, b, c)
465 {-# INLINE zip3 #-}
466 zip3 = zipWith3 (,,)
467
468 unzip :: (Vector v a, Vector v b, Vector v (a,b)) => v (a, b) -> (v a, v b)
469 {-# INLINE unzip #-}
470 unzip xs = (map fst xs, map snd xs)
471
472 unzip3 :: (Vector v a, Vector v b, Vector v c, Vector v (a, b, c)) => v (a, b, c) -> (v a, v b, v c)
473 {-# INLINE unzip3 #-}
474 unzip3 xs = (map (\(a, b, c) -> a) xs, map (\(a, b, c) -> b) xs, map (\(a, b, c) -> c) xs)
475
476 -- Comparisons
477 -- -----------
478
479 eq :: (Vector v a, Eq a) => v a -> v a -> Bool
480 {-# INLINE eq #-}
481 xs `eq` ys = stream xs == stream ys
482
483 cmp :: (Vector v a, Ord a) => v a -> v a -> Ordering
484 {-# INLINE cmp #-}
485 cmp xs ys = compare (stream xs) (stream ys)
486
487 -- Filtering
488 -- ---------
489
490 -- | Drop elements which do not satisfy the predicate
491 filter :: Vector v a => (a -> Bool) -> v a -> v a
492 {-# INLINE filter #-}
493 filter f = unstream . inplace (MStream.filter f) . stream
494
495 -- | Yield the longest prefix of elements satisfying the predicate.
496 takeWhile :: Vector v a => (a -> Bool) -> v a -> v a
497 {-# INLINE takeWhile #-}
498 takeWhile f = unstream . Stream.takeWhile f . stream
499
500 -- | Drop the longest prefix of elements that satisfy the predicate.
501 dropWhile :: Vector v a => (a -> Bool) -> v a -> v a
502 {-# INLINE dropWhile #-}
503 dropWhile f = unstream . Stream.dropWhile f . stream
504
505 -- Searching
506 -- ---------
507
508 infix 4 `elem`
509 -- | Check whether the vector contains an element
510 elem :: (Vector v a, Eq a) => a -> v a -> Bool
511 {-# INLINE elem #-}
512 elem x = Stream.elem x . stream
513
514 infix 4 `notElem`
515 -- | Inverse of `elem`
516 notElem :: (Vector v a, Eq a) => a -> v a -> Bool
517 {-# INLINE notElem #-}
518 notElem x = Stream.notElem x . stream
519
520 -- | Yield 'Just' the first element matching the predicate or 'Nothing' if no
521 -- such element exists.
522 find :: Vector v a => (a -> Bool) -> v a -> Maybe a
523 {-# INLINE find #-}
524 find f = Stream.find f . stream
525
526 -- | Yield 'Just' the index of the first element matching the predicate or
527 -- 'Nothing' if no such element exists.
528 findIndex :: Vector v a => (a -> Bool) -> v a -> Maybe Int
529 {-# INLINE findIndex #-}
530 findIndex f = Stream.findIndex f . stream
531
532 -- Folding
533 -- -------
534
535 -- | Left fold
536 foldl :: Vector v b => (a -> b -> a) -> a -> v b -> a
537 {-# INLINE foldl #-}
538 foldl f z = Stream.foldl f z . stream
539
540 -- | Lefgt fold on non-empty vectors
541 foldl1 :: Vector v a => (a -> a -> a) -> v a -> a
542 {-# INLINE foldl1 #-}
543 foldl1 f = Stream.foldl1 f . stream
544
545 -- | Left fold with strict accumulator
546 foldl' :: Vector v b => (a -> b -> a) -> a -> v b -> a
547 {-# INLINE foldl' #-}
548 foldl' f z = Stream.foldl' f z . stream
549
550 -- | Left fold on non-empty vectors with strict accumulator
551 foldl1' :: Vector v a => (a -> a -> a) -> v a -> a
552 {-# INLINE foldl1' #-}
553 foldl1' f = Stream.foldl1' f . stream
554
555 -- | Right fold
556 foldr :: Vector v a => (a -> b -> b) -> b -> v a -> b
557 {-# INLINE foldr #-}
558 foldr f z = Stream.foldr f z . stream
559
560 -- | Right fold on non-empty vectors
561 foldr1 :: Vector v a => (a -> a -> a) -> v a -> a
562 {-# INLINE foldr1 #-}
563 foldr1 f = Stream.foldr1 f . stream
564
565 -- Specialised folds
566 -- -----------------
567
568 and :: Vector v Bool => v Bool -> Bool
569 {-# INLINE and #-}
570 and = Stream.and . stream
571
572 or :: Vector v Bool => v Bool -> Bool
573 {-# INLINE or #-}
574 or = Stream.or . stream
575
576 sum :: (Vector v a, Num a) => v a -> a
577 {-# INLINE sum #-}
578 sum = Stream.foldl' (+) 0 . stream
579
580 product :: (Vector v a, Num a) => v a -> a
581 {-# INLINE product #-}
582 product = Stream.foldl' (*) 1 . stream
583
584 maximum :: (Vector v a, Ord a) => v a -> a
585 {-# INLINE maximum #-}
586 maximum = Stream.foldl1' max . stream
587
588 minimum :: (Vector v a, Ord a) => v a -> a
589 {-# INLINE minimum #-}
590 minimum = Stream.foldl1' min . stream
591
592 -- Unfolding
593 -- ---------
594
595 unfoldr :: Vector v a => (b -> Maybe (a, b)) -> b -> v a
596 {-# INLINE unfoldr #-}
597 unfoldr f = unstream . Stream.unfoldr f
598
599 -- Scans
600 -- -----
601
602 -- | Prefix scan
603 prescanl :: (Vector v a, Vector v b) => (a -> b -> a) -> a -> v b -> v a
604 {-# INLINE prescanl #-}
605 prescanl f z = unstream . inplace' (MStream.prescanl f z) . stream
606
607 -- | Prefix scan with strict accumulator
608 prescanl' :: (Vector v a, Vector v b) => (a -> b -> a) -> a -> v b -> v a
609 {-# INLINE prescanl' #-}
610 prescanl' f z = unstream . inplace' (MStream.prescanl' f z) . stream
611
612 -- | Suffix scan
613 postscanl :: (Vector v a, Vector v b) => (a -> b -> a) -> a -> v b -> v a
614 {-# INLINE postscanl #-}
615 postscanl f z = unstream . inplace' (MStream.postscanl f z) . stream
616
617 -- | Suffix scan with strict accumulator
618 postscanl' :: (Vector v a, Vector v b) => (a -> b -> a) -> a -> v b -> v a
619 {-# INLINE postscanl' #-}
620 postscanl' f z = unstream . inplace' (MStream.postscanl' f z) . stream
621
622 -- | Haskell-style scan
623 scanl :: (Vector v a, Vector v b) => (a -> b -> a) -> a -> v b -> v a
624 {-# INLINE scanl #-}
625 scanl f z = unstream . Stream.scanl f z . stream
626
627 -- | Haskell-style scan with strict accumulator
628 scanl' :: (Vector v a, Vector v b) => (a -> b -> a) -> a -> v b -> v a
629 {-# INLINE scanl' #-}
630 scanl' f z = unstream . Stream.scanl' f z . stream
631
632 -- | Scan over a non-empty vector
633 scanl1 :: Vector v a => (a -> a -> a) -> v a -> v a
634 {-# INLINE scanl1 #-}
635 scanl1 f = unstream . inplace (MStream.scanl1 f) . stream
636
637 -- | Scan over a non-empty vector with a strict accumulator
638 scanl1' :: Vector v a => (a -> a -> a) -> v a -> v a
639 {-# INLINE scanl1' #-}
640 scanl1' f = unstream . inplace (MStream.scanl1' f) . stream
641
642 -- Enumeration
643 -- -----------
644
645 -- FIXME: The Enum class is irreparably broken, there just doesn't seem to be a
646 -- way to implement this generically. Either specialise this or define a new
647 -- Enum-like class with a proper interface.
648
649 enumFromTo :: (Vector v a, Enum a) => a -> a -> v a
650 {-# INLINE enumFromTo #-}
651 enumFromTo x y = unstream (Stream.enumFromTo x y)
652
653 enumFromThenTo :: (Vector v a, Enum a) => a -> a -> a -> v a
654 {-# INLINE enumFromThenTo #-}
655 enumFromThenTo from next to = fromList [from, next .. to]
656
657 -- | Convert a vector to a list
658 toList :: Vector v a => v a -> [a]
659 {-# INLINE toList #-}
660 toList = Stream.toList . stream
661
662 -- | Convert a list to a vector
663 fromList :: Vector v a => [a] -> v a
664 {-# INLINE fromList #-}
665 fromList = unstream . Stream.fromList
666