494c603e6da6b6491b2a10930ac7a8ca2fa8888c
[darcs-mirrors/vector.git] / Data / Vector / Base.hs
1 {-# LANGUAGE Rank2Types, MultiParamTypeClasses, BangPatterns, CPP #-}
2
3 #include "phases.h"
4
5 module Data.Vector.Base
6 where
7
8 import qualified Data.Vector.Base.Mutable as Mut
9
10 import qualified Data.Vector.Stream as Stream
11 import Data.Vector.Stream ( Stream )
12 import Data.Vector.Stream.Size
13
14 import Prelude hiding ( length, map, zipWith, sum )
15
16 class Base v a where
17 create :: (forall mv m. Mut.Base mv m a => m (mv m a)) -> v a
18
19 length :: v a -> Int
20 unsafeSlice :: v a -> Int -> Int -> v a
21
22 unsafeIndex :: v a -> Int -> (a -> b) -> b
23
24 stream :: Base v a => v a -> Stream a
25 {-# INLINE_STREAM stream #-}
26 stream !v = Stream.unfold get 0 `Stream.sized` Exact n
27 where
28 n = length v
29
30 {-# INLINE get #-}
31 get i | i < n = unsafeIndex v i $ \x -> Just (x, i+1)
32 | otherwise = Nothing
33
34 unstream :: Base v a => Stream a -> v a
35 {-# INLINE_STREAM unstream #-}
36 unstream s = create (Mut.unstream s)
37
38 {-# RULES
39
40 "stream/unstream [Vector.Base]" forall s.
41 stream (unstream s) = s
42
43 #-}
44
45 infixr ++
46 (++) :: Base v a => v a -> v a -> v a
47 {-# INLINE (++) #-}
48 v ++ w = unstream (stream v Stream.++ stream w)
49
50 take :: Base v a => Int -> v a -> v a
51 {-# INLINE take #-}
52 take n = unstream . Stream.take n . stream
53
54 drop :: Base v a => Int -> v a -> v a
55 {-# INLINE drop #-}
56 drop n = unstream . Stream.drop n . stream
57
58 map :: (Base v a, Base v b) => (a -> b) -> v a -> v b
59 {-# INLINE map #-}
60 map f = unstream . Stream.map f . stream
61
62 zipWith :: (Base v a, Base v b, Base v c) => (a -> b -> c) -> v a -> v b -> v c
63 {-# INLINE zipWith #-}
64 zipWith f xs ys = unstream (Stream.zipWith f (stream xs) (stream ys))
65
66 filter :: Base v a => (a -> Bool) -> v a -> v a
67 {-# INLINE filter #-}
68 filter f = unstream . Stream.filter f . stream
69
70 takeWhile :: Base v a => (a -> Bool) -> v a -> v a
71 {-# INLINE takeWhile #-}
72 takeWhile f = unstream . Stream.takeWhile f . stream
73
74 dropWhile :: Base v a => (a -> Bool) -> v a -> v a
75 {-# INLINE dropWhile #-}
76 dropWhile f = unstream . Stream.dropWhile f . stream
77
78 foldl' :: Base v b => (a -> b -> a) -> a -> v b -> a
79 {-# INLINE foldl' #-}
80 foldl' f z = Stream.foldl' f z . stream
81
82 sum :: (Base v a, Num a) => v a -> a
83 {-# INLINE sum #-}
84 sum = foldl' (+) 0
85
86 toList :: Base v a => v a -> [a]
87 {-# INLINE toList #-}
88 toList = Stream.toList . stream
89
90 fromList :: Base v a => [a] -> v a
91 {-# INLINE fromList #-}
92 fromList = unstream . Stream.fromList
93