f404709a015696dc809c3be0517a97898a5d5361
[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 filter :: Base v a => (a -> Bool) -> v a -> v a
51 {-# INLINE filter #-}
52 filter f = unstream . Stream.filter f . stream
53
54 map :: (Base v a, Base v b) => (a -> b) -> v a -> v b
55 {-# INLINE map #-}
56 map f = unstream . Stream.map f . stream
57
58 zipWith :: (Base v a, Base v b, Base v c) => (a -> b -> c) -> v a -> v b -> v c
59 {-# INLINE zipWith #-}
60 zipWith f xs ys = unstream (Stream.zipWith f (stream xs) (stream ys))
61
62 foldl' :: Base v b => (a -> b -> a) -> a -> v b -> a
63 {-# INLINE foldl' #-}
64 foldl' f z = Stream.foldl' f z . stream
65
66 sum :: (Base v a, Num a) => v a -> a
67 {-# INLINE sum #-}
68 sum = foldl' (+) 0
69
70 toList :: Base v a => v a -> [a]
71 {-# INLINE toList #-}
72 toList = Stream.toList . stream
73
74 fromList :: Base v a => [a] -> v a
75 {-# INLINE fromList #-}
76 fromList = unstream . Stream.fromList
77