packages feed

data-diverse 0.6.0.0 → 0.7.0.0

raw patch · 7 files changed

+85/−57 lines, 7 filesdep +criteriondep ~basePVP ok

version bump matches the API change (PVP)

Dependencies added: criterion

Dependency ranges changed: base

API changes (from Hackage documentation)

- Data.Diverse.Many: collect :: Many xs -> c xs r -> Collector c xs r
+ Data.Diverse.Many: collect :: (t ~ Collector c xs, AFoldable t r, Case c xs r) => Many xs -> c xs r -> t r
- Data.Diverse.Many: collectN :: Many xs -> c n xs r -> CollectorN c n xs r
+ Data.Diverse.Many: collectN :: (t ~ CollectorN c n xs, AFoldable t r, Case (c n) xs r) => Many xs -> c n xs r -> t r
- Data.Diverse.Many: forMany :: c xs r -> Many xs -> Collector c xs r
+ Data.Diverse.Many: forMany :: (t ~ Collector c xs, AFoldable t r, Case c xs r) => c xs r -> Many xs -> t r
- Data.Diverse.Many: forManyN :: c n xs r -> Many xs -> CollectorN c n xs r
+ Data.Diverse.Many: forManyN :: (t ~ CollectorN c n xs, AFoldable t r, Case (c n) xs r) => c n xs r -> Many xs -> t r
- Data.Diverse.Many.Internal: Many :: {-# UNPACK #-} !Int -> (Map Int Any) -> Many
+ Data.Diverse.Many.Internal: Many :: {-# UNPACK #-} !Int -> (IntMap Any) -> Many
- Data.Diverse.Many.Internal: collect :: Many xs -> c xs r -> Collector c xs r
+ Data.Diverse.Many.Internal: collect :: (t ~ Collector c xs, AFoldable t r, Case c xs r) => Many xs -> c xs r -> t r
- Data.Diverse.Many.Internal: collectN :: Many xs -> c n xs r -> CollectorN c n xs r
+ Data.Diverse.Many.Internal: collectN :: (t ~ CollectorN c n xs, AFoldable t r, Case (c n) xs r) => Many xs -> c n xs r -> t r
- Data.Diverse.Many.Internal: forMany :: c xs r -> Many xs -> Collector c xs r
+ Data.Diverse.Many.Internal: forMany :: (t ~ Collector c xs, AFoldable t r, Case c xs r) => c xs r -> Many xs -> t r
- Data.Diverse.Many.Internal: forManyN :: c n xs r -> Many xs -> CollectorN c n xs r
+ Data.Diverse.Many.Internal: forManyN :: (t ~ CollectorN c n xs, AFoldable t r, Case (c n) xs r) => c n xs r -> Many xs -> t r

Files

README.md view
@@ -9,3 +9,5 @@ accessed by type or index or label.  Refer to [ManySpec.hs](https://github.com/louispan/data-diverse/blob/master/test/Data/Diverse/ManySpec.hs) and [WhichSpec.hs](https://github.com/louispan/data-diverse/blob/master/test/Data/Diverse/WhichSpec.hs) for example usages.++Iso, Lens and Prisms are provided in [data-diverse-lens](http://hackage.haskell.org/package/data-diverse-lens)
+ bench/Bench.hs view
@@ -0,0 +1,11 @@+module Main where++import Criterion.Main+import qualified Data.Diverse.ManyBench as ManyBench+import qualified Data.Diverse.WhichBench as WhichBench++-- Our benchmark harness.+main = defaultMain [+    ManyBench.bgroup+  , WhichBench.bgroup+  ]
+ bench/Data/Diverse/ManyBench.hs view
@@ -0,0 +1,11 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE TypeApplications #-}++module Data.Diverse.ManyBench where++import qualified Criterion.Main as C+import Data.Diverse++bgroup = C.bgroup "Many"+    [ C.bench "read" (C.whnf (read @(Many '[Int, Bool, Char, Maybe Char])) "5 ./ False ./ 'X' ./ Just 'O' ./ nil")+    ]
+ bench/Data/Diverse/WhichBench.hs view
@@ -0,0 +1,11 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE TypeApplications #-}++module Data.Diverse.WhichBench where++import qualified Criterion.Main as C+import Data.Diverse++bgroup = C.bgroup "Which"+    [ C.bench "read" $ C.whnf (read @(Which '[Int, Bool])) "pickN @0 Proxy 5"+    ]
data-diverse.cabal view
@@ -1,11 +1,15 @@ name:                data-diverse-version:             0.6.0.0+version:             0.7.0.0 synopsis:            Extensible records and polymorphic variants. description:         "Data.Diverse.Many" is an extensible record for any size encoded efficiently as (Int, Map Int Any).                      "Data.Diverse.Which" is a polymorphic variant of possibilities encoded as (Int, Any).                      Provides getters, setters, projection, injection, folds, and catamorphisms;                      accessed by type, index or label.+                      Refer to [ManySpec.hs](https://github.com/louispan/data-diverse/blob/master/test/Data/Diverse/ManySpec.hs) and [WhichSpec.hs](https://github.com/louispan/data-diverse/blob/master/test/Data/Diverse/WhichSpec.hs) for example usages.++                     Iso, Lens and Prisms are provided in [data-diverse-lens](http://hackage.haskell.org/package/data-diverse-lens)+ homepage:            https://github.com/louispan/data-diverse#readme license:             BSD3 license-file:        LICENSE@@ -52,6 +56,18 @@                      , hspec >= 2 && < 3                      , tagged >= 0.8.5 && < 1   ghc-options:         -threaded -rtsopts -with-rtsopts=-N -Wall+  default-language:    Haskell2010++benchmark data-diverse-bench+  type:                exitcode-stdio-1.0+  hs-source-dirs:      bench+  main-is:             Bench.hs+  other-modules:       Data.Diverse.ManyBench+                       Data.Diverse.WhichBench+  build-depends:       base+                     , data-diverse+                     , criterion+  ghc-options:         -O2   default-language:    Haskell2010  source-repository head
src/Data/Diverse/Many/Internal.hs view
@@ -88,7 +88,7 @@ import Data.Diverse.Reiterate import Data.Diverse.TypeLevel import Data.Kind-import qualified Data.Map.Strict as M+import qualified Data.IntMap.Strict as M import Data.Proxy import Data.Tagged import qualified GHC.Generics as G@@ -131,7 +131,7 @@ -- -- The constructor will guarantee the correct number and types of the elements. -- The constructor is only exported in the "Data.Diverse.Many.Internal" module-data Many (xs :: [Type]) = Many {-# UNPACK #-} !Int (M.Map Int Any)+data Many (xs :: [Type]) = Many {-# UNPACK #-} !Int (M.IntMap Any)  -- Inferred role is phantom which is incorrect -- representational means:@@ -164,11 +164,7 @@ instance G.Generic (Many (x ': xs)) where     type Rep (Many (x ': xs)) = (G.Rec0 x) G.:*: (G.Rec0 (Many xs))     from r = ({- G.Rec0 -} G.K1 (front r)) G.:*: ({- G.Rec0 -} G.K1 (aft r))-    -- GHC compilation is SLOW if there is no pragma for recursive typeclass functions for different types-    {-# NOINLINE from #-}     to (({- G.Rec0 -} G.K1 a) G.:*: ({- G.Rec0 -} G.K1 b)) = a ./ b-    -- GHC compilation is SLOW if there is no pragma for recursive typeclass functions for different types-    {-# NOINLINE to #-}  ----------------------------------------------------------------------- @@ -281,7 +277,6 @@ -- \OldRightKey -> OldRightKey - RightOffset + LeftOffset + LeftSize rightKeyForSnoc :: Int -> Int -> Int -> Int -> Int rightKeyForSnoc lo ld ro rk = rk - ro + lo + ld-{-# INLINE rightKeyForSnoc #-}  -- | When appending two maps together, get the function to modify the RightMap's offset -- when adding LeftMap into RightMap.@@ -289,7 +284,6 @@ -- NewRightOffset = OldRightOffset - LeftSize rightOffsetForCons :: Int -> Int -> Int rightOffsetForCons ld ro = ro - ld-{-# INLINE rightOffsetForCons #-}  -- | When appending two maps together, get the function to 'M.mapKeys' the LeftMap -- when adding LeftMap into RightMap.@@ -302,9 +296,8 @@ -- \OldLeftKey -> OldLeftKey - LeftOffset + NewRightOffset (as above) leftKeyForCons :: Int -> Int -> Int -> Int leftKeyForCons lo ro lk = lk - lo + ro-{-# INLINE leftKeyForCons #-} --- | Analogous to 'Prelude.nill'. Named 'nil' to avoid conflicting with 'Prelude.nill'.+-- | Analogous to 'Prelude.null'. Named 'nil' to avoid conflicting with 'Prelude.null'. nil :: Many '[] nil = Many 0 M.empty @@ -335,7 +328,7 @@ infixr 5 ./ -- like Data.List.(:)  -- | Add an element to the right of a Many--- Not named 'snoc' to avoid conflict with 'Control.Lens.snoc'+-- Not named @snoc@ to avoid conflict with 'Control.Lens.snoc' postfix :: Many xs -> y -> Many (Append xs '[y]) postfix (Many lo lm) y = Many lo     (M.insert (rightKeyForSnoc lo (M.size lm) 0 0)@@ -343,12 +336,16 @@         lm) infixl 5 `postfix` --- | 'snoc' mnemonic: Many is larger '\.' than the smaller element+-- | Infix version of 'postfix'.+--+-- Mnemonic: Many is larger '\.' than the smaller element (\.) :: Many xs -> y -> Many (Append xs '[y]) (\.) = postfix infixl 5 \. --- | 'append' mnemonic: 'cons' './' with an extra slash (meaning 'Many') in front.+-- | Infix version of 'append'.+--+-- Mnemonic: 'prefix' './' with an extra slash (meaning 'Many') in front. (/./) :: Many xs -> Many ys -> Many (Append xs ys) (/./) = append infixr 5 /./ -- like (++)@@ -415,8 +412,8 @@  -- | Getter by label. Get the value of the field with tag @label@ which can be any type -- not just @KnownSymbol@.--- @ --+-- @ -- let y = False './' Tagged \@Foo \'X' './' Tagged @"Hi" True './' 'nil' -- 'fetchL' \@Foo Proxy y \`shouldBe` Tagged \@Foo \'X' -- 'fetchL' \@"Hi" Proxy y \`shouldBe` Tagged \@"Hi" True@@ -510,7 +507,7 @@ -----------------------------------------------------------------------  -- | Internal function for construction - do not expose!-fromList' :: Ord k => [(k, WrappedAny)] -> M.Map k Any+fromList' :: [(Int, WrappedAny)] -> M.IntMap Any fromList' xs = M.fromList (coerce xs)  -----------------------------------------------------------------------@@ -538,8 +535,7 @@        -- use of head/tail here is safe as we are guaranteed the length from the typelist        x = Partial.head xs        xs' = Partial.tail xs-    -- GHC compilation is SLOW if there is no pragma for recursive typeclass functions for different types-    {-# NOINLINE afoldr #-}+    {-# INLINABLE afoldr #-} -- This makes compiling tests a little faster than with no pragma  forMany' :: c xs r -> Many xs -> CollectorAny c xs r forMany' c (Many _ xs) = CollectorAny c (snd <$> M.toAscList xs)@@ -563,8 +559,7 @@        -- use of head/tail here is safe as we are guaranteed the length from the typelist        x = Partial.head xs        xs' = Partial.tail xs-    -- GHC compilation is SLOW if there is no pragma for recursive typeclass functions for different types-    {-# NOINLINE afoldr #-}+    {-# INLINABLE afoldr #-} -- This makes compiling tests a little faster than with no pragma  forManyN' :: c n xs r -> Many xs -> CollectorAnyN c n xs r forManyN' c (Many _ xs) = CollectorAnyN c (snd <$> M.toAscList xs)@@ -583,7 +578,7 @@ instance AFoldable (Collector c '[]) r where     afoldr _ z _ = z --- | Folds values by 'reiterate'ing 'Emit'ters through the @xs@ typelist.+-- | Folds values by 'reiterate'ing 'Case's through the @xs@ typelist. instance ( Case c (x ': xs) r          , Reiterate c (x ': xs)          , AFoldable (Collector c xs) r@@ -594,24 +589,21 @@        -- use of head/tail here is safe as we are guaranteed the length from the typelist        v = unsafeCoerce $ Partial.head xs        xs' = Partial.tail xs-    -- GHC compilation is SLOW if there is no pragma for recursive typeclass functions for different types-    {-# NOINLINE afoldr #-}+    {-# INLINABLE afoldr #-} -- This makes compiling tests a little faster than with no pragma  -----------------------------------------------------------------------  -- | Folds any 'Many', even with indistinct types.--- Given __distinct__ handlers for the fields in 'Many', create a 'Collector'+-- Given __distinct__ handlers for the fields in 'Many', create 'AFoldable' -- of the results of running the handlers over the fields in 'Many'. ----- The 'Collector' is 'AFoldable' to combine the results.--- -- @ -- let x = (5 :: Int) './' False './' \'X' './' Just \'O' './' (6 :: Int) './' Just \'A' './' 'nil' --     y = show \@Int './' show \@Char './' show \@(Maybe Char) './' show \@Bool './' 'nil' -- 'afoldr' (:) [] ('forMany' ('Data.Diverse.Cases.cases' y) x) \`shouldBe` --     [\"5", \"False", \"\'X'", \"Just \'O'", \"6", \"Just \'A'"] -- @-forMany :: c xs r -> Many xs -> Collector c xs r+forMany :: (t ~ Collector c xs, AFoldable t r, Case c xs r) => c xs r -> Many xs -> t r forMany c (Many _ xs) = Collector c (snd <$> M.toAscList xs)  -- | This is @flip 'forMany'@@@ -622,7 +614,7 @@ -- 'afoldr' (:) [] ('collect' x ('Data.Diverse.Cases.cases' y)) \`shouldBe` --     [\"5", \"False", \"\'X'", \"Just \'O'", \"6", \"Just \'A'"] -- @-collect :: Many xs -> c xs r -> Collector c xs r+collect :: (t ~ Collector c xs, AFoldable t r, Case c xs r) => Many xs -> c xs r -> t r collect = flip forMany  -----------------------------------------------------------------------@@ -645,22 +637,19 @@        -- use of head/tail here is safe as we are guaranteed the length from the typelist        v = unsafeCoerce $ Partial.head xs        xs' = Partial.tail xs-    -- GHC compilation is SLOW if there is no pragma for recursive typeclass functions for different types-    {-# NOINLINE afoldr #-}+    {-# INLINABLE afoldr #-} -- This makes compiling tests a little faster than with no pragma  -- | Folds any 'Many', even with indistinct types.--- Given __index__ handlers for the fields in 'Many', create a 'CollectorN'+-- Given __index__ handlers for the fields in 'Many', create 'AFoldable' -- of the results of running the handlers over the fields in 'Many'. ----- The 'CollectorN' is 'AFoldable' to combine the results.--- -- @ -- let x = (5 :: Int) './' False './' \'X' './' Just \'O' './' (6 :: Int) './' Just \'A' './' 'nil' --     y = show \@Int './' show \@Bool './' show \@Char './' show \@(Maybe Char) './' show \@Int './' show \@(Maybe Char) './' 'nil' -- 'afoldr' (:) [] ('forManyN' ('Data.Diverse.Cases.casesN' y) x) \`shouldBe` --     [\"5", \"False", \"\'X'", \"Just \'O'", \"6", \"Just \'A'"] -- @-forManyN :: c n xs r -> Many xs -> CollectorN c n xs r+forManyN :: (t ~ CollectorN c n xs, AFoldable t r, Case (c n) xs r) => c n xs r -> Many xs -> t r forManyN c (Many _ xs) = CollectorN c (snd <$> M.toAscList xs)  -- | This is @flip 'forManyN'@@@ -671,7 +660,7 @@ -- 'afoldr' (:) [] ('collectN' x ('Data.Diverse.Cases.casesN' y)) \`shouldBe` --     [\"5", \"False", \"\'X'", \"Just \'O'", \"6", \"Just \'A'"] -- @-collectN :: Many xs -> c n xs r -> CollectorN c n xs r+collectN :: (t ~ CollectorN c n xs, AFoldable t r, Case (c n) xs r) => Many xs -> c n xs r -> t r collectN = flip forManyN  -----------------------------------------------------------------------@@ -956,8 +945,7 @@     ls == rs = case front' ls == front' rs of         False -> False         _ -> (aft' ls) == (aft' rs)-    -- GHC compilation is SLOW if there is no pragma for recursive typeclass functions for different types-    {-# NOINLINE (==) #-}+    {-# INLINABLE (==) #-} -- This makes compiling tests a little faster than with no pragma  -- | Two 'Many's are equal if all their fields equal instance Eq (Many_ xs) => Eq (Many xs) where@@ -973,8 +961,7 @@         LT -> LT         GT -> GT         EQ -> compare (aft' ls) (aft' rs)-    -- GHC compilation is SLOW if there is no pragma for recursive typeclass functions for different types-    {-# NOINLINE compare #-}+    {-# INLINABLE compare #-} -- This makes compiling tests a little faster than with no pragma  -- | Two 'Many's are ordered by 'compare'ing their fields in index order instance Ord (Many_ xs) => Ord (Many xs) where@@ -997,10 +984,9 @@         cons_prec = 5 -- infixr 5 prefix         -- use of front here is safe as we are guaranteed the length from the typelist         v = unsafeCoerce (Partial.head xs) :: x-    -- GHC compilation is SLOW if there is no pragma for recursive typeclass functions for different types-    {-# NOINLINE showsPrec #-}+    {-# INLINABLE showsPrec #-} -- This makes compiling tests a little faster than with no pragma --- | Two 'Many's are equal if all their fields equal+-- | @show (5 :: Int) './' False './' \'X' './' Just \'O' './' 'nil' == "5 ./ False ./ 'X' ./ Just 'O' ./ nil" == @ instance Show (Many_ xs) => Show (Many xs) where     showsPrec d xs = showsPrec d (toMany_ xs) @@ -1021,8 +1007,7 @@         pure $ prefix' a as       where         cons_prec = 5 -- infixr `prefix`-    -- GHC compilation is SLOW if there is no pragma for recursive typeclass functions for different types-    {-# NOINLINE readPrec #-}+    {-# INLINABLE readPrec #-} -- This makes compiling tests a little faster than with no pragma  -- | @read "5 ./ False ./ 'X' ./ Just 'O' ./ nil" == (5 :: Int) './' False './' \'X' './' Just \'O' './' 'nil'@ instance Read (Many_ xs) => Read (Many xs) where
src/Data/Diverse/Which/Internal.hs view
@@ -464,10 +464,8 @@         case trial0 v of             Right a -> case' c a             Left v' -> reduce (Switch (reiterate c)) v'-    -- GHC compilation is SLOW if there is no pragma for recursive typeclass functions for different types-    -- Using INLINEABLE instead of NOLINE so that ghc 8.2.1 can optimize to single case statement-    -- See https://ghc.haskell.org/trac/ghc/ticket/12877-    {-# INLINEABLE reduce #-}+    -- Ghc 8.2.1 can optimize to single case statement. See https://ghc.haskell.org/trac/ghc/ticket/12877+    {-# INLINABLE reduce #-} -- This makes compiling tests a little faster than with no pragma  -- | Terminating case of the loop, ensuring that a instance of @Case '[]@ -- with an empty typelist is not required.@@ -517,10 +515,8 @@         case trial0 v of             Right a -> case' c a             Left v' -> reduce (SwitchN (reiterateN c)) v'-    -- GHC compilation is SLOW if there is no pragma for recursive typeclass functions for different types-    -- Using INLINEABLE instead of NOLINE so that ghc 8.2.1 can optimize to single case statement-    -- See https://ghc.haskell.org/trac/ghc/ticket/12877-    {-# INLINEABLE reduce #-}+    -- Ghc 8.2.1 can optimize to single case statement. See https://ghc.haskell.org/trac/ghc/ticket/12877+    {-# INLINABLE reduce #-} -- This makes compiling tests a little faster than with no pragma  -- | Terminating case of the loop, ensuring that a instance of @Case '[]@ -- with an empty typelist is not required.@@ -643,11 +639,7 @@ instance (Read x, WhichRead (Which_ (x' ': xs))) => WhichRead (Which_ (x ': x' ': xs)) where     whichReadPrec i j = readWhich_ i j                <|> (diversify0' <$> (whichReadPrec i (j + 1) :: ReadPrec (Which_ (x' ': xs))))-    -- GHC compilation is SLOW if there is no pragma for recursive typeclass functions for different types-    -- Using INLINEABLE instead of NOLINE so that ghc 8.2.1 can optimize to single case statement-    -- See https://ghc.haskell.org/trac/ghc/ticket/12877-    {-# INLINEABLE whichReadPrec #-}-+    {-# INLINABLE whichReadPrec #-} -- This makes compiling tests a little faster than with no pragma  -- | This 'Read' instance tries to read using the each type in the typelist, using the first successful type read. instance WhichRead (Which_ (x ': xs)) =>