Comments
[darcs-mirrors/vector.git] / Data / Vector / Generic / New.hs
1 {-# LANGUAGE Rank2Types #-}
2
3 -- |
4 -- Module : Data.Vector.Generic.New
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 -- Purely functional interface to initialisation of mutable vectors
13 --
14
15 #include "phases.h"
16
17 module Data.Vector.Generic.New (
18 New(..), run, unstream, transform, accum, update, reverse,
19 slice, init, tail, take, drop
20 ) where
21
22 import qualified Data.Vector.Generic.Mutable as MVector
23 import Data.Vector.Generic.Mutable ( MVector, MVectorPure )
24
25 import Data.Vector.Fusion.Stream ( Stream, MStream )
26 import qualified Data.Vector.Fusion.Stream as Stream
27
28 import Control.Monad ( liftM )
29 import Prelude hiding ( init, tail, take, drop, reverse, map, filter )
30
31 newtype New a = New (forall m mv. MVector mv m a => m (mv a))
32
33 run :: MVector mv m a => New a -> m (mv a)
34 {-# INLINE run #-}
35 run (New p) = p
36
37 apply :: (forall mv a. MVectorPure mv a => mv a -> mv a) -> New a -> New a
38 {-# INLINE apply #-}
39 apply f (New p) = New (liftM f p)
40
41 modify :: New a -> (forall m mv. MVector mv m a => mv a -> m ()) -> New a
42 {-# INLINE modify #-}
43 modify (New p) q = New (do { v <- p; q v; return v })
44
45 unstream :: Stream a -> New a
46 {-# INLINE_STREAM unstream #-}
47 unstream s = New (MVector.unstream s)
48
49 transform :: (forall m. Monad m => MStream m a -> MStream m a) -> New a -> New a
50 {-# INLINE_STREAM transform #-}
51 transform f (New p) = New (MVector.transform f =<< p)
52
53 {-# RULES
54
55 "transform/transform [New]"
56 forall (f :: forall m. Monad m => MStream m a -> MStream m a)
57 (g :: forall m. Monad m => MStream m a -> MStream m a)
58 p .
59 transform f (transform g p) = transform (f . g) p
60
61 "transform/unstream [New]"
62 forall (f :: forall m. Monad m => MStream m a -> MStream m a)
63 s.
64 transform f (unstream s) = unstream (f s)
65
66 #-}
67
68 slice :: New a -> Int -> Int -> New a
69 {-# INLINE_STREAM slice #-}
70 slice m i n = apply (\v -> MVector.slice v i n) m
71
72 init :: New a -> New a
73 {-# INLINE_STREAM init #-}
74 init m = apply (\v -> MVector.slice v 0 (MVector.length v - 1)) m
75
76 tail :: New a -> New a
77 {-# INLINE_STREAM tail #-}
78 tail m = apply (\v -> MVector.slice v 1 (MVector.length v - 1)) m
79
80 take :: Int -> New a -> New a
81 {-# INLINE_STREAM take #-}
82 take n m = apply (\v -> MVector.slice v 0 (min n (MVector.length v))) m
83
84 drop :: Int -> New a -> New a
85 {-# INLINE_STREAM drop #-}
86 drop n m = apply (\v -> MVector.slice v n (max 0 (MVector.length v - n))) m
87
88 {-# RULES
89
90 "slice/unstream [New]" forall s i n.
91 slice (unstream s) i n = unstream (Stream.extract s i n)
92
93 "init/unstream [New]" forall s.
94 init (unstream s) = unstream (Stream.init s)
95
96 "tail/unstream [New]" forall s.
97 tail (unstream s) = unstream (Stream.tail s)
98
99 "take/unstream [New]" forall n s.
100 take n (unstream s) = unstream (Stream.take n s)
101
102 "drop/unstream [New]" forall n s.
103 drop n (unstream s) = unstream (Stream.drop n s)
104
105 #-}
106
107 accum :: (a -> b -> a) -> New a -> Stream (Int, b) -> New a
108 {-# INLINE_STREAM accum #-}
109 accum f m s = modify m (\v -> MVector.accum f v s)
110
111 update :: New a -> Stream (Int, a) -> New a
112 {-# INLINE_STREAM update #-}
113 update m s = modify m (\v -> MVector.update v s)
114
115 reverse :: New a -> New a
116 {-# INLINE_STREAM reverse #-}
117 reverse m = modify m (MVector.reverse)
118