1{-# LANGUAGE CPP, Rank2Types, FlexibleContexts, MultiParamTypeClasses #-}
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
15module Data.Vector.Generic.New (
16  New(..), create, run, runPrim, apply, modify, modifyWithBundle,
17  unstream, transform, unstreamR, transformR,
18  slice, init, tail, take, drop,
19  unsafeSlice, unsafeInit, unsafeTail
20) where
21
22import qualified Data.Vector.Generic.Mutable as MVector
23
24import           Data.Vector.Generic.Base ( Vector, Mutable )
25
26import           Data.Vector.Fusion.Bundle ( Bundle )
27import qualified Data.Vector.Fusion.Bundle as Bundle
28import           Data.Vector.Fusion.Stream.Monadic ( Stream )
29import           Data.Vector.Fusion.Bundle.Size
30
31import Control.Monad.Primitive
32import Control.Monad.ST ( ST )
33import Control.Monad  ( liftM )
34import Prelude hiding ( init, tail, take, drop, reverse, map, filter )
35
36-- Data.Vector.Internal.Check is unused
37#define NOT_VECTOR_MODULE
38#include "vector.h"
39
40data New v a = New (forall s. ST s (Mutable v s a))
41
42create :: (forall s. ST s (Mutable v s a)) -> New v a
43{-# INLINE create #-}
44create p = New p
45
46run :: New v a -> ST s (Mutable v s a)
47{-# INLINE run #-}
48run (New p) = p
49
50runPrim :: PrimMonad m => New v a -> m (Mutable v (PrimState m) a)
51{-# INLINE runPrim #-}
52runPrim (New p) = primToPrim p
53
54apply :: (forall s. Mutable v s a -> Mutable v s a) -> New v a -> New v a
55{-# INLINE apply #-}
56apply f (New p) = New (liftM f p)
57
58modify :: (forall s. Mutable v s a -> ST s ()) -> New v a -> New v a
59{-# INLINE modify #-}
60modify f (New p) = New (do { v <- p; f v; return v })
61
62modifyWithBundle :: (forall s. Mutable v s a -> Bundle u b -> ST s ())
63                 -> New v a -> Bundle u b -> New v a
64{-# INLINE_FUSED modifyWithBundle #-}
65modifyWithBundle f (New p) s = s `seq` New (do { v <- p; f v s; return v })
66
67unstream :: Vector v a => Bundle v a -> New v a
68{-# INLINE_FUSED unstream #-}
69unstream s = s `seq` New (MVector.vunstream s)
70
71transform
72  :: Vector v a => (forall m. Monad m => Stream m a -> Stream m a)
73                -> (Size -> Size) -> New v a -> New v a
74{-# INLINE_FUSED transform #-}
75transform f _ (New p) = New (MVector.transform f =<< p)
76
77{-# RULES
78
79"transform/transform [New]"
80  forall (f1 :: forall m. Monad m => Stream m a -> Stream m a)
81         (f2 :: forall m. Monad m => Stream m a -> Stream m a)
82         g1 g2 p .
83  transform f1 g1 (transform f2 g2 p) = transform (f1 . f2) (g1 . g2) p
84
85"transform/unstream [New]"
86  forall (f :: forall m. Monad m => Stream m a -> Stream m a)
87         g s.
88  transform f g (unstream s) = unstream (Bundle.inplace f g s)  #-}
89
90
91
92
93unstreamR :: Vector v a => Bundle v a -> New v a
94{-# INLINE_FUSED unstreamR #-}
95unstreamR s = s `seq` New (MVector.unstreamR s)
96
97transformR
98  :: Vector v a => (forall m. Monad m => Stream m a -> Stream m a)
99                -> (Size -> Size) -> New v a -> New v a
100{-# INLINE_FUSED transformR #-}
101transformR f _ (New p) = New (MVector.transformR f =<< p)
102
103{-# RULES
104
105"transformR/transformR [New]"
106  forall (f1 :: forall m. Monad m => Stream m a -> Stream m a)
107         (f2 :: forall m. Monad m => Stream m a -> Stream m a)
108         g1 g2
109         p .
110  transformR f1 g1 (transformR f2 g2 p) = transformR (f1 . f2) (g1 . g2) p
111
112"transformR/unstreamR [New]"
113  forall (f :: forall m. Monad m => Stream m a -> Stream m a)
114         g s.
115  transformR f g (unstreamR s) = unstreamR (Bundle.inplace f g s)  #-}
116
117
118
119slice :: Vector v a => Int -> Int -> New v a -> New v a
120{-# INLINE_FUSED slice #-}
121slice i n m = apply (MVector.slice i n) m
122
123init :: Vector v a => New v a -> New v a
124{-# INLINE_FUSED init #-}
125init m = apply MVector.init m
126
127tail :: Vector v a => New v a -> New v a
128{-# INLINE_FUSED tail #-}
129tail m = apply MVector.tail m
130
131take :: Vector v a => Int -> New v a -> New v a
132{-# INLINE_FUSED take #-}
133take n m = apply (MVector.take n) m
134
135drop :: Vector v a => Int -> New v a -> New v a
136{-# INLINE_FUSED drop #-}
137drop n m = apply (MVector.drop n) m
138
139unsafeSlice :: Vector v a => Int -> Int -> New v a -> New v a
140{-# INLINE_FUSED unsafeSlice #-}
141unsafeSlice i n m = apply (MVector.unsafeSlice i n) m
142
143unsafeInit :: Vector v a => New v a -> New v a
144{-# INLINE_FUSED unsafeInit #-}
145unsafeInit m = apply MVector.unsafeInit m
146
147unsafeTail :: Vector v a => New v a -> New v a
148{-# INLINE_FUSED unsafeTail #-}
149unsafeTail m = apply MVector.unsafeTail m
150
151{-# RULES
152
153"slice/unstream [New]" forall i n s.
154  slice i n (unstream s) = unstream (Bundle.slice i n s)
155
156"init/unstream [New]" forall s.
157  init (unstream s) = unstream (Bundle.init s)
158
159"tail/unstream [New]" forall s.
160  tail (unstream s) = unstream (Bundle.tail s)
161
162"take/unstream [New]" forall n s.
163  take n (unstream s) = unstream (Bundle.take n s)
164
165"drop/unstream [New]" forall n s.
166  drop n (unstream s) = unstream (Bundle.drop n s)
167
168"unsafeSlice/unstream [New]" forall i n s.
169  unsafeSlice i n (unstream s) = unstream (Bundle.slice i n s)
170
171"unsafeInit/unstream [New]" forall s.
172  unsafeInit (unstream s) = unstream (Bundle.init s)
173
174"unsafeTail/unstream [New]" forall s.
175  unsafeTail (unstream s) = unstream (Bundle.tail s)   #-}
176
177
178
179