Allow streams to produce entire vectors as well as individual elements
[darcs-mirrors/vector.git] / Data / Vector / Generic / Base.hs
1 {-# LANGUAGE Rank2Types, MultiParamTypeClasses, FlexibleContexts,
2 TypeFamilies, ScopedTypeVariables, BangPatterns #-}
3 {-# OPTIONS_HADDOCK hide #-}
4
5 -- |
6 -- Module : Data.Vector.Generic.Base
7 -- Copyright : (c) Roman Leshchinskiy 2008-2010
8 -- License : BSD-style
9 --
10 -- Maintainer : Roman Leshchinskiy <rl@cse.unsw.edu.au>
11 -- Stability : experimental
12 -- Portability : non-portable
13 --
14 -- Class of pure vectors
15 --
16
17 module Data.Vector.Generic.Base (
18 Vector(..), Mutable
19 ) where
20
21 import Data.Vector.Generic.Mutable.Base ( MVector )
22 import qualified Data.Vector.Generic.Mutable.Base as M
23
24 import Control.Monad.Primitive
25
26 -- | @Mutable v s a@ is the mutable version of the pure vector type @v a@ with
27 -- the state token @s@
28 --
29 type family Mutable (v :: * -> *) :: * -> * -> *
30
31 -- | Class of immutable vectors. Every immutable vector is associated with its
32 -- mutable version through the 'Mutable' type family. Methods of this class
33 -- should not be used directly. Instead, "Data.Vector.Generic" and other
34 -- Data.Vector modules provide safe and fusible wrappers.
35 --
36 -- Minimum complete implementation:
37 --
38 -- * 'basicUnsafeFreeze'
39 --
40 -- * 'basicUnsafeThaw'
41 --
42 -- * 'basicLength'
43 --
44 -- * 'basicUnsafeSlice'
45 --
46 -- * 'basicUnsafeIndexM'
47 --
48 class MVector (Mutable v) a => Vector v a where
49 -- | /Assumed complexity: O(1)/
50 --
51 -- Unsafely convert a mutable vector to its immutable version
52 -- without copying. The mutable vector may not be used after
53 -- this operation.
54 basicUnsafeFreeze :: PrimMonad m => Mutable v (PrimState m) a -> m (v a)
55
56 -- | /Assumed complexity: O(1)/
57 --
58 -- Unsafely convert an immutable vector to its mutable version without
59 -- copying. The immutable vector may not be used after this operation.
60 basicUnsafeThaw :: PrimMonad m => v a -> m (Mutable v (PrimState m) a)
61
62 -- | /Assumed complexity: O(1)/
63 --
64 -- Yield the length of the vector.
65 basicLength :: v a -> Int
66
67 -- | /Assumed complexity: O(1)/
68 --
69 -- Yield a slice of the vector without copying it. No range checks are
70 -- performed.
71 basicUnsafeSlice :: Int -- ^ starting index
72 -> Int -- ^ length
73 -> v a -> v a
74
75 -- | /Assumed complexity: O(1)/
76 --
77 -- Yield the element at the given position in a monad. No range checks are
78 -- performed.
79 --
80 -- The monad allows us to be strict in the vector if we want. Suppose we had
81 --
82 -- > unsafeIndex :: v a -> Int -> a
83 --
84 -- instead. Now, if we wanted to copy a vector, we'd do something like
85 --
86 -- > copy mv v ... = ... unsafeWrite mv i (unsafeIndex v i) ...
87 --
88 -- For lazy vectors, the indexing would not be evaluated which means that we
89 -- would retain a reference to the original vector in each element we write.
90 -- This is not what we want!
91 --
92 -- With 'basicUnsafeIndexM', we can do
93 --
94 -- > copy mv v ... = ... case basicUnsafeIndexM v i of
95 -- > Box x -> unsafeWrite mv i x ...
96 --
97 -- which does not have this problem because indexing (but not the returned
98 -- element!) is evaluated immediately.
99 --
100 basicUnsafeIndexM :: Monad m => v a -> Int -> m a
101
102 -- | /Assumed complexity: O(n)/
103 --
104 -- Copy an immutable vector into a mutable one. The two vectors must have
105 -- the same length but this is not checked.
106 --
107 -- Instances of 'Vector' should redefine this method if they wish to support
108 -- an efficient block copy operation.
109 --
110 -- Default definition: copying basic on 'basicUnsafeIndexM' and
111 -- 'basicUnsafeWrite'.
112 basicUnsafeCopy :: PrimMonad m => Mutable v (PrimState m) a -> v a -> m ()
113
114 {-# INLINE basicUnsafeCopy #-}
115 basicUnsafeCopy !dst !src = do_copy 0
116 where
117 !n = basicLength src
118
119 do_copy i | i < n = do
120 x <- basicUnsafeIndexM src i
121 M.basicUnsafeWrite dst i x
122 do_copy (i+1)
123 | otherwise = return ()
124
125 -- | Evaluate @a@ as far as storing it in a vector would and yield @b@.
126 -- The @v a@ argument only fixes the type and is not touched. The method is
127 -- only used for optimisation purposes. Thus, it is safe for instances of
128 -- 'Vector' to evaluate @a@ less than it would be when stored in a vector
129 -- although this might result in suboptimal code.
130 --
131 -- > elemseq v x y = (singleton x `asTypeOf` v) `seq` y
132 --
133 -- Default defintion: @a@ is not evaluated at all
134 --
135 elemseq :: v a -> a -> b -> b
136
137 {-# INLINE elemseq #-}
138 elemseq _ = \_ x -> x
139
140