Add clone and change fusion rules accordingly
[darcs-mirrors/vector.git] / Data / Vector / Generic / New.hs
1 {-# LANGUAGE Rank2Types, FlexibleContexts #-}
2
3 -- |
4 -- Module : Data.Vector.Generic.New
5 -- Copyright : (c) Roman Leshchinskiy 2008-2010
6 -- License : BSD-style
7 --
8 -- Maintainer : Roman Leshchinskiy <rl@cse.unsw.edu.au>
9 -- Stability : experimental
10 -- Portability : non-portable
11 --
12 -- Purely functional interface to initialisation of mutable vectors
13 --
14
15 module Data.Vector.Generic.New (
16 New(..), create, run, apply, modify,
17 unstream, transform, unstreamR, transformR,
18 accum, update, reverse,
19 slice, init, tail, take, drop,
20 unsafeSlice, unsafeInit, unsafeTail,
21 unsafeAccum, unsafeUpdate
22 ) where
23
24 import qualified Data.Vector.Generic.Mutable as MVector
25 import Data.Vector.Generic.Mutable ( MVector )
26
27 import Data.Vector.Generic.Base ( Vector, Mutable )
28
29 import Data.Vector.Fusion.Stream ( Stream, MStream )
30 import qualified Data.Vector.Fusion.Stream as Stream
31
32 import Control.Monad.ST ( ST )
33 import Control.Monad ( liftM )
34 import Prelude hiding ( init, tail, take, drop, reverse, map, filter )
35
36 #include "vector.h"
37
38 data New v a = New (forall s. ST s (Mutable v s a))
39
40 create :: (forall s. ST s (Mutable v s a)) -> New v a
41 {-# INLINE create #-}
42 create = New
43
44 run :: New v a -> ST s (Mutable v s a)
45 {-# INLINE run #-}
46 run (New p) = p
47
48 apply :: (forall s. Mutable v s a -> Mutable v s a) -> New v a -> New v a
49 {-# INLINE apply #-}
50 apply f (New p) = New (liftM f p)
51
52 modify :: (forall s. Mutable v s a -> ST s ()) -> New v a -> New v a
53 {-# INLINE modify #-}
54 modify f (New p) = New (do { v <- p; f v; return v })
55
56 unstream :: Vector v a => Stream a -> New v a
57 {-# INLINE_STREAM unstream #-}
58 unstream s = s `seq` New (MVector.unstream s)
59
60 transform :: Vector v a =>
61 (forall m. Monad m => MStream m a -> MStream m a) -> New v a -> New v a
62 {-# INLINE_STREAM transform #-}
63 transform f (New p) = New (MVector.transform f =<< p)
64
65 {-# RULES
66
67 "transform/transform [New]"
68 forall (f :: forall m. Monad m => MStream m a -> MStream m a)
69 (g :: forall m. Monad m => MStream m a -> MStream m a)
70 p .
71 transform f (transform g p) = transform (f . g) p
72
73 "transform/unstream [New]"
74 forall (f :: forall m. Monad m => MStream m a -> MStream m a)
75 s.
76 transform f (unstream s) = unstream (f s)
77
78 #-}
79
80
81 unstreamR :: Vector v a => Stream a -> New v a
82 {-# INLINE_STREAM unstreamR #-}
83 unstreamR s = s `seq` New (MVector.unstreamR s)
84
85 transformR :: Vector v a =>
86 (forall m. Monad m => MStream m a -> MStream m a) -> New v a -> New v a
87 {-# INLINE_STREAM transformR #-}
88 transformR f (New p) = New (MVector.transformR f =<< p)
89
90 {-# RULES
91
92 "transformR/transformR [New]"
93 forall (f :: forall m. Monad m => MStream m a -> MStream m a)
94 (g :: forall m. Monad m => MStream m a -> MStream m a)
95 p .
96 transformR f (transformR g p) = transformR (f . g) p
97
98 "transformR/unstreamR [New]"
99 forall (f :: forall m. Monad m => MStream m a -> MStream m a)
100 s.
101 transformR f (unstreamR s) = unstreamR (f s)
102
103 #-}
104
105 slice :: Vector v a => Int -> Int -> New v a -> New v a
106 {-# INLINE_STREAM slice #-}
107 slice i n m = apply (MVector.slice i n) m
108
109 init :: Vector v a => New v a -> New v a
110 {-# INLINE_STREAM init #-}
111 init m = apply MVector.init m
112
113 tail :: Vector v a => New v a -> New v a
114 {-# INLINE_STREAM tail #-}
115 tail m = apply MVector.tail m
116
117 take :: Vector v a => Int -> New v a -> New v a
118 {-# INLINE_STREAM take #-}
119 take n m = apply (MVector.take n) m
120
121 drop :: Vector v a => Int -> New v a -> New v a
122 {-# INLINE_STREAM drop #-}
123 drop n m = apply (MVector.drop n) m
124
125 unsafeSlice :: Vector v a => Int -> Int -> New v a -> New v a
126 {-# INLINE_STREAM unsafeSlice #-}
127 unsafeSlice i n m = apply (MVector.unsafeSlice i n) m
128
129 unsafeInit :: Vector v a => New v a -> New v a
130 {-# INLINE_STREAM unsafeInit #-}
131 unsafeInit m = apply MVector.unsafeInit m
132
133 unsafeTail :: Vector v a => New v a -> New v a
134 {-# INLINE_STREAM unsafeTail #-}
135 unsafeTail m = apply MVector.unsafeTail m
136
137 {-# RULES
138
139 "slice/unstream [New]" forall i n s.
140 slice i n (unstream s) = unstream (Stream.slice i n s)
141
142 "init/unstream [New]" forall s.
143 init (unstream s) = unstream (Stream.init s)
144
145 "tail/unstream [New]" forall s.
146 tail (unstream s) = unstream (Stream.tail s)
147
148 "take/unstream [New]" forall n s.
149 take n (unstream s) = unstream (Stream.take n s)
150
151 "drop/unstream [New]" forall n s.
152 drop n (unstream s) = unstream (Stream.drop n s)
153
154 "unsafeSlice/unstream [New]" forall i n s.
155 unsafeSlice i n (unstream s) = unstream (Stream.slice i n s)
156
157 "unsafeInit/unstream [New]" forall s.
158 unsafeInit (unstream s) = unstream (Stream.init s)
159
160 "unsafeTail/unstream [New]" forall s.
161 unsafeTail (unstream s) = unstream (Stream.tail s)
162
163 #-}
164
165 unsafeAccum
166 :: Vector v a => (a -> b -> a) -> New v a -> Stream (Int, b) -> New v a
167 {-# INLINE_STREAM unsafeAccum #-}
168 unsafeAccum f m s = s `seq` modify (\v -> MVector.unsafeAccum f v s) m
169
170 accum :: Vector v a => (a -> b -> a) -> New v a -> Stream (Int, b) -> New v a
171 {-# INLINE_STREAM accum #-}
172 accum f m s = s `seq` modify (\v -> MVector.accum f v s) m
173
174 unsafeUpdate :: Vector v a => New v a -> Stream (Int, a) -> New v a
175 {-# INLINE_STREAM unsafeUpdate #-}
176 unsafeUpdate m s = s `seq` modify (\v -> MVector.unsafeUpdate v s) m
177
178 update :: Vector v a => New v a -> Stream (Int, a) -> New v a
179 {-# INLINE_STREAM update #-}
180 update m s = s `seq` modify (\v -> MVector.update v s) m
181
182 reverse :: Vector v a => New v a -> New v a
183 {-# INLINE_STREAM reverse #-}
184 reverse m = modify (MVector.reverse) m
185