diff --git a/vector/src/Data/Vector/Unboxed.hs b/vector/src/Data/Vector/Unboxed.hs index 3b57cbd4..47328d43 100644 --- a/vector/src/Data/Vector/Unboxed.hs +++ b/vector/src/Data/Vector/Unboxed.hs @@ -13,14 +13,42 @@ -- Stability : experimental -- Portability : non-portable -- --- Adaptive unboxed vectors. The implementation is based on type families +-- Adaptive unboxed vectors. The implementation is based on data families -- and picks an efficient, specialised representation for every element type. --- For example, unboxed vectors of pairs are represented as pairs of unboxed --- vectors. +-- For example, vector of fixed size primitives are backed by +-- 'Data.Vector.Primitive.Vector', unboxed vectors of tuples are represented +-- as tuples of unboxed vectors (see 'zip'\/'unzip'). Note that vector is +-- only adaptive types could pick boxed representation for data type\/field +-- of record. However all library instances are backed by unboxed array(s). -- --- Implementing unboxed vectors for new data types can be very easy. Here is --- how the library does this for 'Complex' by simply wrapping vectors of --- pairs. +-- Defining new instances of unboxed vectors is somewhat complicated since +-- it requires defining two data family and two type class instances. Latter +-- two could be generated using @GeneralizedNewtypeDeriving@ or @DerivingVia@ +-- +-- >>> :set -XTypeFamilies -XStandaloneDeriving -XMultiParamTypeClasses -XGeneralizedNewtypeDeriving +-- >>> +-- >>> import qualified Data.Vector.Generic as VG +-- >>> import qualified Data.Vector.Generic.Mutable as VGM +-- >>> import qualified Data.Vector.Unboxed as VU +-- >>> +-- >>> newtype Foo = Foo Int +-- >>> +-- >>> newtype instance VU.MVector s Foo = MV_Int (VU.MVector s Int) +-- >>> newtype instance VU.Vector Foo = V_Int (VU.Vector Int) +-- >>> deriving instance VGM.MVector VU.MVector Foo +-- >>> deriving instance VG.Vector VU.Vector Foo +-- >>> instance VU.Unbox Foo +-- +-- For other data types we have several newtype wrappers for use with +-- @DerivingVia@. See documentation of 'As' and 'IsoUnbox' for defining +-- unboxed vector of product types. 'UnboxViaPrim' could be used to define +-- vector of instances of 'Data.Vector.Primitive.Prim'. Similarly +-- 'DoNotUnboxStrict'/'DoNotUnboxLazy'/'DoNotUnboxNormalForm' could be used +-- to represent polymorphic fields as boxed vectors. +-- +-- Or if everything else fails instances could be written by hand. +-- Here is how the library does this for 'Complex' by simply wrapping +-- vectors of pairs. -- -- @ -- newtype instance 'MVector' s ('Complex' a) = MV_Complex ('MVector' s (a,a)) @@ -38,26 +66,6 @@ -- -- instance ('RealFloat' a, 'Unbox' a) => 'Unbox' ('Complex' a) -- @ --- --- For newtypes, defining instances is easier since one could use --- @GeneralizedNewtypeDeriving@ in order to derive instances for --- 'Data.Vector.Generic.Vector' and 'Data.Vector.Generic.Mutable.MVector', --- since they're very cumbersome to write by hand: --- --- >>> :set -XTypeFamilies -XStandaloneDeriving -XMultiParamTypeClasses -XGeneralizedNewtypeDeriving --- >>> --- >>> import qualified Data.Vector.Generic as VG --- >>> import qualified Data.Vector.Generic.Mutable as VGM --- >>> import qualified Data.Vector.Unboxed as VU --- >>> --- >>> newtype Foo = Foo Int --- >>> --- >>> newtype instance VU.MVector s Foo = MV_Int (VU.MVector s Int) --- >>> newtype instance VU.Vector Foo = V_Int (VU.Vector Int) --- >>> deriving instance VGM.MVector VU.MVector Foo --- >>> deriving instance VG.Vector VU.Vector Foo --- >>> instance VU.Unbox Foo - module Data.Vector.Unboxed ( -- * Unboxed vectors Vector(V_UnboxAs, V_UnboxViaPrim), MVector(..), Unbox, @@ -132,12 +140,15 @@ module Data.Vector.Unboxed ( -- ** Zipping zipWith, zipWith3, zipWith4, zipWith5, zipWith6, izipWith, izipWith3, izipWith4, izipWith5, izipWith6, + -- *** Zipping tuples + -- $zip zip, zip3, zip4, zip5, zip6, -- ** Monadic zipping zipWithM, izipWithM, zipWithM_, izipWithM_, -- ** Unzipping + -- $unzip unzip, unzip3, unzip4, unzip5, unzip6, -- * Working with predicates @@ -977,6 +988,26 @@ iforM_ = G.iforM_ -- Zipping -- ------- +-- $zip +-- +-- Following functions could be used to construct vector of tuples +-- from tuple of vectors. This operation is done in /O(1)/ time and +-- will share underlying buffers. +-- +-- Note that variants from "Data.Vector.Generic" doesn't have this +-- property. + +-- $unzip +-- +-- Following functions could be used to access underlying +-- representation of array of tuples. They convert array to tuple of +-- arrays. This operation is done in /O(1)/ time and will share +-- underlying buffers. +-- +-- Note that variants from "Data.Vector.Generic" doesn't have this +-- property. + + -- | /O(min(m,n))/ Zip two vectors with the given function. zipWith :: (Unbox a, Unbox b, Unbox c) => (a -> b -> c) -> Vector a -> Vector b -> Vector c diff --git a/vector/src/Data/Vector/Unboxed/Base.hs b/vector/src/Data/Vector/Unboxed/Base.hs index a4f91ee6..723af33b 100644 --- a/vector/src/Data/Vector/Unboxed/Base.hs +++ b/vector/src/Data/Vector/Unboxed/Base.hs @@ -1027,9 +1027,6 @@ instance NFData a => G.Vector Vector (DoNotUnboxNormalForm a) where instance NFData a => Unbox (DoNotUnboxNormalForm a) -instance NFData a => NFData (DoNotUnboxNormalForm a) where - {-# INLINE rnf #-} - rnf = rnf . coerce @(DoNotUnboxNormalForm a) @a deriveNewtypeInstances((), Any, Bool, Any, V_Any, MV_Any) deriveNewtypeInstances((), All, Bool, All, V_All, MV_All)