large-generics 0.1.0.0 → 0.2.0.0
raw patch · 5 files changed
+43/−24 lines, 5 filesdep +primitivedep −vectordep ~aesonPVP ok
version bump matches the API change (PVP)
Dependencies added: primitive
Dependencies removed: vector
Dependency ranges changed: aeson
API changes (from Hackage documentation)
- Data.Record.Generic: Rep :: Vector (f Any) -> Rep f a
+ Data.Record.Generic: Rep :: SmallArray (f Any) -> Rep f a
- Data.Record.Generic.Rep: Rep :: Vector (f Any) -> Rep f a
+ Data.Record.Generic.Rep: Rep :: SmallArray (f Any) -> Rep f a
- Data.Record.Generic.Rep.Internal: Rep :: Vector (f Any) -> Rep f a
+ Data.Record.Generic.Rep.Internal: Rep :: SmallArray (f Any) -> Rep f a
Files
- CHANGELOG.md +4/−0
- large-generics.cabal +5/−2
- src/Data/Record/Generic/Rep.hs +20/−8
- src/Data/Record/Generic/Rep/Internal.hs +10/−11
- src/Data/Record/Generic/SOP.hs +4/−3
CHANGELOG.md view
@@ -1,5 +1,9 @@ # Revision history for large-generics +## 0.2.0.0 -- 2022-04-06++* Use `SmallArray` instead of `Vector`+ ## 0.1.0.0 -- 2022-03-23 * First public release
large-generics.cabal view
@@ -1,6 +1,6 @@ cabal-version: 2.4 name: large-generics-version: 0.1.0.0+version: 0.2.0.0 synopsis: Generic programming API for large-records and large-anon description: The large-generics package offers a style of generic programming inspired by generics-sop, but optimized for@@ -45,7 +45,10 @@ , aeson >= 1.4.4 && < 2.1 , generics-sop >= 0.5 && < 0.6 , sop-core >= 0.5 && < 0.6- , vector >= 0.12 && < 0.13+ , primitive >= 0.7 && < 0.8++ if impl(ghc >= 8.10)+ ghc-options: -Wunused-packages test-suite test-large-generics type:
src/Data/Record/Generic/Rep.hs view
@@ -55,14 +55,14 @@ , zipWith ) -import Data.Proxy+import Control.Monad (forM_) import Data.Functor.Identity import Data.Functor.Product+import Data.Primitive.SmallArray+import Data.Proxy import Data.SOP.Classes (fn_2) import Unsafe.Coerce (unsafeCoerce) -import qualified Data.Vector as V- import Data.Record.Generic import Data.Record.Generic.Rep.Internal @@ -82,11 +82,13 @@ getAtIndex :: Index a x -> Rep f a -> f x getAtIndex (UnsafeIndex ix) (Rep v) =- unsafeCoerce $ V.unsafeIndex v ix+ unsafeCoerce $ indexSmallArray v ix putAtIndex :: Index a x -> f x -> Rep f a -> Rep f a-putAtIndex (UnsafeIndex ix) x (Rep v) = Rep $- V.unsafeUpd v [(ix, unsafeCoerce x)]+putAtIndex (UnsafeIndex ix) x (Rep v) = Rep $ runSmallArray $ do+ v' <- thawSmallArray v 0 (sizeofSmallArray v)+ writeSmallArray v' ix (noInlineUnsafeCo x)+ return v' updateAtIndex :: Functor m@@ -96,7 +98,14 @@ updateAtIndex ix f a = (\x -> putAtIndex ix x a) <$> f (getAtIndex ix a) allIndices :: forall a. Generic a => Rep (Index a) a-allIndices = Rep $ V.generate (recordSize (metadata (Proxy @a))) UnsafeIndex+allIndices = Rep $ runSmallArray $ do+ v <- newSmallArray size undefined+ forM_ [0 .. size - 1] $ \i ->+ writeSmallArray v i (UnsafeIndex i)+ return v+ where+ size :: Int+ size = recordSize (metadata (Proxy @a)) -- | Map with index --@@ -117,7 +126,10 @@ -------------------------------------------------------------------------------} pure :: forall f a. Generic a => (forall x. f x) -> Rep f a-pure f = Rep (V.replicate (recordSize (metadata (Proxy @a))) f)+pure f = Rep $ runSmallArray $ newSmallArray size f+ where+ size :: Int+ size = recordSize (metadata (Proxy @a)) cpure :: (Generic a, Constraints a c)
src/Data/Record/Generic/Rep/Internal.hs view
@@ -24,13 +24,12 @@ import qualified Prelude import Data.Coerce (coerce)+import Data.Foldable (toList)+import Data.Primitive.SmallArray import Data.SOP.BasicFunctors-import Data.Vector (Vector) import GHC.Exts (Any) import Unsafe.Coerce (unsafeCoerce) -import qualified Data.Vector as V- {------------------------------------------------------------------------------- Representation -------------------------------------------------------------------------------}@@ -39,7 +38,7 @@ -- -- The @f@ parameter describes which functor has been applied to all fields of -- the record; in other words @Rep I@ is isomorphic to the record itself.-newtype Rep f a = Rep (Vector (f Any))+newtype Rep f a = Rep (SmallArray (f Any)) type role Rep representational nominal @@ -62,24 +61,24 @@ -------------------------------------------------------------------------------} collapse :: Rep (K a) b -> [a]-collapse (Rep v) = coerce (V.toList v)+collapse (Rep v) = coerce (toList v) -- | Convert 'Rep' to list toListAny :: Rep f a -> [f Any]-toListAny (Rep v) = V.toList v+toListAny (Rep v) = toList v -- | Convert list to 'Rep' -- -- Does not check that the list has the right number of elements. unsafeFromList :: [b] -> Rep (K b) a-unsafeFromList = Rep . V.fromList . Prelude.map K+unsafeFromList = Rep . smallArrayFromList . Prelude.map K -- | Convert list to 'Rep' -- -- Does not check that the list has the right number of elements, nor the -- types of those elements. unsafeFromListAny :: [f Any] -> Rep f a-unsafeFromListAny = Rep . V.fromList+unsafeFromListAny = Rep . smallArrayFromList {------------------------------------------------------------------------------- Some specialised instances for 'Rep@@ -87,12 +86,12 @@ instance Show x => Show (Rep (K x) a) where show (Rep v) =- show $ Prelude.map unK (V.toList v)+ show $ Prelude.map unK (toList v) instance Eq x => Eq (Rep (K x) a) where Rep v == Rep v' =- Prelude.map unK (V.toList v)- == Prelude.map unK (V.toList v')+ Prelude.map unK (toList v)+ == Prelude.map unK (toList v') {------------------------------------------------------------------------------- Auxiliary
src/Data/Record/Generic/SOP.hs view
@@ -25,14 +25,15 @@ , glowerBound ) where +import Data.Foldable (toList) import Data.Kind+import Data.Primitive.SmallArray import Data.Proxy import Data.SOP.Dict (all_NP) import Generics.SOP (SOP(..), NS(..), NP(..), SListI, All, Code, Compose) import GHC.Exts (Any) import GHC.TypeLits (Symbol) -import qualified Data.Vector as V import qualified Generics.SOP as SOP import Data.Record.Generic@@ -59,14 +60,14 @@ fromSOP :: SListI (MetadataOf a) => NP (Field f) (MetadataOf a) -> Rep f a fromSOP =- Rep . V.fromList . SOP.hcollapse . SOP.hmap conv+ Rep . smallArrayFromList . SOP.hcollapse . SOP.hmap conv where conv :: Field f field -> K (f Any) field conv (Field fx) = K $ noInlineUnsafeCo fx toSOP :: SListI (MetadataOf a) => Rep f a -> Maybe (NP (Field f) (MetadataOf a)) toSOP (Rep v) =- SOP.hmap conv <$> SOP.fromList (V.toList v)+ SOP.hmap conv <$> SOP.fromList (toList v) where conv :: K (f Any) field -> Field f field conv (K fx) = Field (noInlineUnsafeCo fx)