Generic Vector framework
[darcs-mirrors/vector.git] / Data / Vector / Base.hs
1 {-# LANGUAGE TypeFamilies, FlexibleContexts, RankNTypes, 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. Mut.Base mv a => Mut.Trans mv (mv 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 map :: (Base v a, Base v b) => (a -> b) -> v a -> v b
51 {-# INLINE map #-}
52 map f = unstream . Stream.map f . stream
53
54 zipWith :: (Base v a, Base v b, Base v c) => (a -> b -> c) -> v a -> v b -> v c
55 {-# INLINE zipWith #-}
56 zipWith f xs ys = unstream (Stream.zipWith f (stream xs) (stream ys))
57
58 foldl' :: Base v b => (a -> b -> a) -> a -> v b -> a
59 {-# INLINE foldl' #-}
60 foldl' f z = Stream.foldl' f z . stream
61
62 sum :: (Base v a, Num a) => v a -> a
63 {-# INLINE sum #-}
64 sum = foldl' (+) 0
65