|
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