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