|
13 | 13 | -- Stability : experimental |
14 | 14 | -- Portability : non-portable |
15 | 15 | -- |
16 | | --- Adaptive unboxed vectors. The implementation is based on type families |
| 16 | +-- Adaptive unboxed vectors. The implementation is based on data families |
17 | 17 | -- and picks an efficient, specialised representation for every element type. |
18 | | --- For example, unboxed vectors of pairs are represented as pairs of unboxed |
19 | | --- vectors. |
| 18 | +-- For example, vector of fixed size primitives are backed by |
| 19 | +-- 'Data.Vector.Primitive.Vector', unboxed vectors of tuples are represented |
| 20 | +-- as tuples of unboxed vectors (see 'zip'\/'unzip'). Note that vector is |
| 21 | +-- only adaptive types could pick boxed representation for data type\/field |
| 22 | +-- of record. However all library instances are backed by unboxed array(s). |
20 | 23 | -- |
21 | | --- Implementing unboxed vectors for new data types can be very easy. Here is |
22 | | --- how the library does this for 'Complex' by simply wrapping vectors of |
23 | | --- pairs. |
| 24 | +-- Defining new instances of unboxed vectors is somewhat complicated since |
| 25 | +-- it requires defining two data family and two type class instances. Latter |
| 26 | +-- two could be generated using @GeneralizedNewtypeDeriving@ or @DerivingVia@ |
| 27 | +-- |
| 28 | +-- >>> :set -XTypeFamilies -XStandaloneDeriving -XMultiParamTypeClasses -XGeneralizedNewtypeDeriving |
| 29 | +-- >>> |
| 30 | +-- >>> import qualified Data.Vector.Generic as VG |
| 31 | +-- >>> import qualified Data.Vector.Generic.Mutable as VGM |
| 32 | +-- >>> import qualified Data.Vector.Unboxed as VU |
| 33 | +-- >>> |
| 34 | +-- >>> newtype Foo = Foo Int |
| 35 | +-- >>> |
| 36 | +-- >>> newtype instance VU.MVector s Foo = MV_Int (VU.MVector s Int) |
| 37 | +-- >>> newtype instance VU.Vector Foo = V_Int (VU.Vector Int) |
| 38 | +-- >>> deriving instance VGM.MVector VU.MVector Foo |
| 39 | +-- >>> deriving instance VG.Vector VU.Vector Foo |
| 40 | +-- >>> instance VU.Unbox Foo |
| 41 | +-- |
| 42 | +-- For other data types we have several newtype wrappers for use with |
| 43 | +-- @DerivingVia@. See documentation of 'As' and 'IsoUnbox' for defining |
| 44 | +-- unboxed vector of product types. 'UnboxViaPrim' could be used to define |
| 45 | +-- vector of instances of 'Data.Vector.Primitive.Prim'. Similarly |
| 46 | +-- 'DoNotUnboxStrict'/'DoNotUnboxLazy'/'DoNotUnboxNormalForm' could be used |
| 47 | +-- to represent polymorphic fields as boxed vectors. |
| 48 | +-- |
| 49 | +-- Or if everything else fails instances could be written by hand. |
| 50 | +-- Here is how the library does this for 'Complex' by simply wrapping |
| 51 | +-- vectors of pairs. |
24 | 52 | -- |
25 | 53 | -- @ |
26 | 54 | -- newtype instance 'MVector' s ('Complex' a) = MV_Complex ('MVector' s (a,a)) |
|
38 | 66 | -- |
39 | 67 | -- instance ('RealFloat' a, 'Unbox' a) => 'Unbox' ('Complex' a) |
40 | 68 | -- @ |
41 | | --- |
42 | | --- For newtypes, defining instances is easier since one could use |
43 | | --- @GeneralizedNewtypeDeriving@ in order to derive instances for |
44 | | --- 'Data.Vector.Generic.Vector' and 'Data.Vector.Generic.Mutable.MVector', |
45 | | --- since they're very cumbersome to write by hand: |
46 | | --- |
47 | | --- >>> :set -XTypeFamilies -XStandaloneDeriving -XMultiParamTypeClasses -XGeneralizedNewtypeDeriving |
48 | | --- >>> |
49 | | --- >>> import qualified Data.Vector.Generic as VG |
50 | | --- >>> import qualified Data.Vector.Generic.Mutable as VGM |
51 | | --- >>> import qualified Data.Vector.Unboxed as VU |
52 | | --- >>> |
53 | | --- >>> newtype Foo = Foo Int |
54 | | --- >>> |
55 | | --- >>> newtype instance VU.MVector s Foo = MV_Int (VU.MVector s Int) |
56 | | --- >>> newtype instance VU.Vector Foo = V_Int (VU.Vector Int) |
57 | | --- >>> deriving instance VGM.MVector VU.MVector Foo |
58 | | --- >>> deriving instance VG.Vector VU.Vector Foo |
59 | | --- >>> instance VU.Unbox Foo |
60 | | - |
61 | 69 | module Data.Vector.Unboxed ( |
62 | 70 | -- * Unboxed vectors |
63 | 71 | Vector(V_UnboxAs, V_UnboxViaPrim), MVector(..), Unbox, |
@@ -132,12 +140,15 @@ module Data.Vector.Unboxed ( |
132 | 140 | -- ** Zipping |
133 | 141 | zipWith, zipWith3, zipWith4, zipWith5, zipWith6, |
134 | 142 | izipWith, izipWith3, izipWith4, izipWith5, izipWith6, |
| 143 | + -- *** Zipping tuples |
| 144 | + -- $zip |
135 | 145 | zip, zip3, zip4, zip5, zip6, |
136 | 146 |
|
137 | 147 | -- ** Monadic zipping |
138 | 148 | zipWithM, izipWithM, zipWithM_, izipWithM_, |
139 | 149 |
|
140 | 150 | -- ** Unzipping |
| 151 | + -- $unzip |
141 | 152 | unzip, unzip3, unzip4, unzip5, unzip6, |
142 | 153 |
|
143 | 154 | -- * Working with predicates |
@@ -977,6 +988,26 @@ iforM_ = G.iforM_ |
977 | 988 | -- Zipping |
978 | 989 | -- ------- |
979 | 990 |
|
| 991 | +-- $zip |
| 992 | +-- |
| 993 | +-- Following functions could be used to construct vector of tuples |
| 994 | +-- from tuple of vectors. This operation is done in /O(1)/ time and |
| 995 | +-- will share underlying buffers. |
| 996 | +-- |
| 997 | +-- Note that variants from "Data.Vector.Generic" doesn't have this |
| 998 | +-- property. |
| 999 | + |
| 1000 | +-- $unzip |
| 1001 | +-- |
| 1002 | +-- Following functions could be used to access underlying |
| 1003 | +-- representation of array of tuples. They convert array to tuple of |
| 1004 | +-- arrays. This operation is done in /O(1)/ time and will share |
| 1005 | +-- underlying buffers. |
| 1006 | +-- |
| 1007 | +-- Note that variants from "Data.Vector.Generic" doesn't have this |
| 1008 | +-- property. |
| 1009 | + |
| 1010 | + |
980 | 1011 | -- | /O(min(m,n))/ Zip two vectors with the given function. |
981 | 1012 | zipWith :: (Unbox a, Unbox b, Unbox c) |
982 | 1013 | => (a -> b -> c) -> Vector a -> Vector b -> Vector c |
|
0 commit comments