monoidmap 0.0.0.0 → 0.0.0.1
raw patch · 10 files changed
+111/−45 lines, 10 filesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
- Examples.MultiMap.Instances.MultiMap1: instance (GHC.Classes.Eq k, GHC.Classes.Eq v) => GHC.Classes.Eq (Examples.MultiMap.Instances.MultiMap1.MultiMap k v)
- Examples.MultiMap.Instances.MultiMap1: instance (GHC.Classes.Ord k, GHC.Classes.Ord v) => Examples.MultiMap.Class.MultiMap Examples.MultiMap.Instances.MultiMap1.MultiMap k v
- Examples.MultiMap.Instances.MultiMap1: instance (GHC.Show.Show k, GHC.Show.Show v) => GHC.Show.Show (Examples.MultiMap.Instances.MultiMap1.MultiMap k v)
- Examples.MultiMap.Instances.MultiMap1: newtype MultiMap k v
- Examples.MultiMap.Instances.MultiMap2: instance (GHC.Classes.Eq k, GHC.Classes.Eq v) => GHC.Classes.Eq (Examples.MultiMap.Instances.MultiMap2.MultiMap k v)
- Examples.MultiMap.Instances.MultiMap2: instance (GHC.Classes.Ord k, GHC.Classes.Ord v) => Examples.MultiMap.Class.MultiMap Examples.MultiMap.Instances.MultiMap2.MultiMap k v
- Examples.MultiMap.Instances.MultiMap2: instance (GHC.Show.Show k, GHC.Show.Show v) => GHC.Show.Show (Examples.MultiMap.Instances.MultiMap2.MultiMap k v)
- Examples.MultiMap.Instances.MultiMap2: newtype MultiMap k v
- Examples.MultiMap.Instances.MultiMap3: instance (GHC.Classes.Eq k, GHC.Classes.Eq v) => GHC.Classes.Eq (Examples.MultiMap.Instances.MultiMap3.MultiMap k v)
- Examples.MultiMap.Instances.MultiMap3: instance (GHC.Classes.Ord k, GHC.Classes.Ord v) => Examples.MultiMap.Class.MultiMap Examples.MultiMap.Instances.MultiMap3.MultiMap k v
- Examples.MultiMap.Instances.MultiMap3: instance (GHC.Show.Show k, GHC.Show.Show v) => GHC.Show.Show (Examples.MultiMap.Instances.MultiMap3.MultiMap k v)
- Examples.MultiMap.Instances.MultiMap3: newtype MultiMap k v
- Examples.MultiMap.Instances.MultiMap4: instance (GHC.Classes.Eq k, GHC.Classes.Eq v) => GHC.Classes.Eq (Examples.MultiMap.Instances.MultiMap4.MultiMap k v)
- Examples.MultiMap.Instances.MultiMap4: instance (GHC.Classes.Ord k, GHC.Classes.Ord v) => Examples.MultiMap.Class.MultiMap Examples.MultiMap.Instances.MultiMap4.MultiMap k v
- Examples.MultiMap.Instances.MultiMap4: instance (GHC.Show.Show k, GHC.Show.Show v) => GHC.Show.Show (Examples.MultiMap.Instances.MultiMap4.MultiMap k v)
- Examples.MultiMap.Instances.MultiMap4: newtype MultiMap k v
+ Examples.MultiMap: class (Eq (m k v), Ord k, Ord v) => MultiMap m k v
+ Examples.MultiMap: empty :: MultiMap m k v => m k v
+ Examples.MultiMap: fromList :: MultiMap m k v => [(k, Set v)] -> m k v
+ Examples.MultiMap: insert :: MultiMap m k v => k -> Set v -> m k v -> m k v
+ Examples.MultiMap: intersection :: MultiMap m k v => m k v -> m k v -> m k v
+ Examples.MultiMap: isSubmapOf :: MultiMap m k v => m k v -> m k v -> Bool
+ Examples.MultiMap: lookup :: MultiMap m k v => k -> m k v -> Set v
+ Examples.MultiMap: nonNull :: MultiMap m k v => m k v -> Bool
+ Examples.MultiMap: nonNullCount :: MultiMap m k v => m k v -> Int
+ Examples.MultiMap: nonNullKey :: MultiMap m k v => k -> m k v -> Bool
+ Examples.MultiMap: nonNullKeys :: MultiMap m k v => m k v -> Set k
+ Examples.MultiMap: null :: MultiMap m k v => m k v -> Bool
+ Examples.MultiMap: remove :: MultiMap m k v => k -> Set v -> m k v -> m k v
+ Examples.MultiMap: toList :: MultiMap m k v => m k v -> [(k, Set v)]
+ Examples.MultiMap: union :: MultiMap m k v => m k v -> m k v -> m k v
+ Examples.MultiMap: update :: MultiMap m k v => k -> Set v -> m k v -> m k v
+ Examples.MultiMap.Instances.MultiMap1: instance (GHC.Classes.Eq k, GHC.Classes.Eq v) => GHC.Classes.Eq (Examples.MultiMap.Instances.MultiMap1.MultiMap1 k v)
+ Examples.MultiMap.Instances.MultiMap1: instance (GHC.Classes.Ord k, GHC.Classes.Ord v) => Examples.MultiMap.Class.MultiMap Examples.MultiMap.Instances.MultiMap1.MultiMap1 k v
+ Examples.MultiMap.Instances.MultiMap1: instance (GHC.Show.Show k, GHC.Show.Show v) => GHC.Show.Show (Examples.MultiMap.Instances.MultiMap1.MultiMap1 k v)
+ Examples.MultiMap.Instances.MultiMap1: newtype MultiMap1 k v
+ Examples.MultiMap.Instances.MultiMap2: instance (GHC.Classes.Eq k, GHC.Classes.Eq v) => GHC.Classes.Eq (Examples.MultiMap.Instances.MultiMap2.MultiMap2 k v)
+ Examples.MultiMap.Instances.MultiMap2: instance (GHC.Classes.Ord k, GHC.Classes.Ord v) => Examples.MultiMap.Class.MultiMap Examples.MultiMap.Instances.MultiMap2.MultiMap2 k v
+ Examples.MultiMap.Instances.MultiMap2: instance (GHC.Show.Show k, GHC.Show.Show v) => GHC.Show.Show (Examples.MultiMap.Instances.MultiMap2.MultiMap2 k v)
+ Examples.MultiMap.Instances.MultiMap2: newtype MultiMap2 k v
+ Examples.MultiMap.Instances.MultiMap3: instance (GHC.Classes.Eq k, GHC.Classes.Eq v) => GHC.Classes.Eq (Examples.MultiMap.Instances.MultiMap3.MultiMap3 k v)
+ Examples.MultiMap.Instances.MultiMap3: instance (GHC.Classes.Ord k, GHC.Classes.Ord v) => Examples.MultiMap.Class.MultiMap Examples.MultiMap.Instances.MultiMap3.MultiMap3 k v
+ Examples.MultiMap.Instances.MultiMap3: instance (GHC.Show.Show k, GHC.Show.Show v) => GHC.Show.Show (Examples.MultiMap.Instances.MultiMap3.MultiMap3 k v)
+ Examples.MultiMap.Instances.MultiMap3: newtype MultiMap3 k v
+ Examples.MultiMap.Instances.MultiMap4: instance (GHC.Classes.Eq k, GHC.Classes.Eq v) => GHC.Classes.Eq (Examples.MultiMap.Instances.MultiMap4.MultiMap4 k v)
+ Examples.MultiMap.Instances.MultiMap4: instance (GHC.Classes.Ord k, GHC.Classes.Ord v) => Examples.MultiMap.Class.MultiMap Examples.MultiMap.Instances.MultiMap4.MultiMap4 k v
+ Examples.MultiMap.Instances.MultiMap4: instance (GHC.Show.Show k, GHC.Show.Show v) => GHC.Show.Show (Examples.MultiMap.Instances.MultiMap4.MultiMap4 k v)
+ Examples.MultiMap.Instances.MultiMap4: newtype MultiMap4 k v
- Examples.MultiMap.Instances.MultiMap1: MultiMap :: Map k (Set v) -> MultiMap k v
+ Examples.MultiMap.Instances.MultiMap1: MultiMap :: Map k (Set v) -> MultiMap1 k v
- Examples.MultiMap.Instances.MultiMap2: MultiMap :: Map k (Set v) -> MultiMap k v
+ Examples.MultiMap.Instances.MultiMap2: MultiMap :: Map k (Set v) -> MultiMap2 k v
- Examples.MultiMap.Instances.MultiMap3: MultiMap :: Map k (NESet v) -> MultiMap k v
+ Examples.MultiMap.Instances.MultiMap3: MultiMap :: Map k (NESet v) -> MultiMap3 k v
- Examples.MultiMap.Instances.MultiMap4: MultiMap :: MonoidMap k (Set v) -> MultiMap k v
+ Examples.MultiMap.Instances.MultiMap4: MultiMap :: MonoidMap k (Set v) -> MultiMap4 k v
Files
- CHANGELOG.md +4/−0
- monoidmap.cabal +2/−1
- src/examples/Examples/MultiMap.hs +46/−0
- src/examples/Examples/MultiMap/Class.hs +30/−18
- src/examples/Examples/MultiMap/Instances/MultiMap1.hs +5/−5
- src/examples/Examples/MultiMap/Instances/MultiMap2.hs +3/−3
- src/examples/Examples/MultiMap/Instances/MultiMap3.hs +3/−3
- src/examples/Examples/MultiMap/Instances/MultiMap4.hs +4/−4
- src/internal/Data/MonoidMap/Internal.hs +1/−2
- src/test/Examples/MultiMapSpec.hs +13/−9
CHANGELOG.md view
@@ -1,3 +1,7 @@+# 0.0.0.1++Revised `MultiMap` examples and documentation.+ # 0.0.0.0 Initial release.
monoidmap.cabal view
@@ -1,6 +1,6 @@ cabal-version: 3.0 name: monoidmap-version: 0.0.0.0+version: 0.0.0.1 bug-reports: https://github.com/jonathanknowles/monoidmap/issues license: Apache-2.0 license-file: LICENSE@@ -101,6 +101,7 @@ hs-source-dirs: src/examples exposed-modules:+ Examples.MultiMap Examples.MultiMap.Class Examples.MultiMap.Instances.MultiMap1 Examples.MultiMap.Instances.MultiMap2
+ src/examples/Examples/MultiMap.hs view
@@ -0,0 +1,46 @@+{-# OPTIONS_GHC -fno-warn-unused-imports #-}+-- |+-- Copyright: © 2022–2023 Jonathan Knowles+-- License: Apache-2.0+--+-- Provides the 'MultiMap' class, which models a total relation from unique+-- keys to sets of values.+--+-- = Implementations+--+-- The following example implementations are provided:+--+-- +----------------+------------------------+---------++-- | Implementation | Types used | Lawful? |+-- +================+=============+==========+=========++-- | 'MultiMap1' | 'Map' | 'Set' | 💥 No |+-- +----------------+-------------+----------+---------++-- | 'MultiMap2' | 'Map' | 'Set' | ✅ Yes |+-- +----------------+-------------+----------+---------++-- | 'MultiMap3' | 'Map' | 'NESet' | ✅ Yes |+-- +----------------+-------------+----------+---------++-- | 'MultiMap4' | 'MonoidMap' | 'Set' | ✅ Yes |+-- +----------------+-------------+----------+---------++--+module Examples.MultiMap+ ( MultiMap (..)+ ) where++import Data.Map.Strict+ ( Map )+import Data.MonoidMap+ ( MonoidMap )+import Data.Set+ ( Set )+import Data.Set.NonEmpty+ ( NESet )+import Examples.MultiMap.Class+ ( MultiMap (..) )+import Examples.MultiMap.Instances.MultiMap1+ ( MultiMap1 )+import Examples.MultiMap.Instances.MultiMap2+ ( MultiMap2 )+import Examples.MultiMap.Instances.MultiMap3+ ( MultiMap3 )+import Examples.MultiMap.Instances.MultiMap4+ ( MultiMap4 )
src/examples/Examples/MultiMap/Class.hs view
@@ -115,25 +115,31 @@ -- -- Instances must satisfy the following properties: --- -- /Idempotence/+ -- __/Idempotence/__+ -- -- > union m m ≡ m --- -- /Identity/- -- > union empty m ≡ m- -- > union m empty ≡ m+ -- __/Identity/__ --- -- /Commutativity/+ -- > union empty m ≡ m+ -- > union m empty ≡ m+ --+ -- __/Commutativity/__+ -- -- > union m1 m2 ≡ union m2 m1 --- -- /Associativity/+ -- __/Associativity/__+ -- -- > union m1 (union m2 m3) ≡ -- > union (union m1 m2) m3 --- -- /Containment/+ -- __/Containment/__+ -- -- > m1 `isSubmapOf` union m1 m2 -- > m2 `isSubmapOf` union m1 m2 --- -- /Distributivity/+ -- __/Distributivity/__+ -- -- > lookup k (union m1 m2) ≡ Set.union (lookup k m1) -- > (lookup k m2) --@@ -143,25 +149,31 @@ -- -- Instances must satisfy the following properties: --- -- /Idempotence/+ -- __/Idempotence/__+ -- -- > intersection m m ≡ m --- -- /Identity/- -- > intersection empty m ≡ empty- -- > intersection m empty ≡ empty+ -- __/Identity/__ --- -- /Commutativity/+ -- > intersection empty m ≡ empty+ -- > intersection m empty ≡ empty+ --+ -- __/Commutativity/__+ -- -- > intersection m1 m2 ≡ intersection m2 m1 --- -- /Associativity/+ -- __/Associativity/__+ -- -- > intersection m1 (intersection m2 m3) ≡ -- > intersection (intersection m1 m2) m3 --- -- /Containment/- -- intersection m1 m2 `isSubmapOf` m1- -- intersection m1 m2 `isSubmapOf` m2+ -- __/Containment/__ --- -- /Distributivity/+ -- > intersection m1 m2 `isSubmapOf` m1+ -- > intersection m1 m2 `isSubmapOf` m2+ --+ -- __/Distributivity/__+ -- -- > lookup k (intersection m1 m2) ≡ Set.intersection (lookup k m1) -- > (lookup k m2) --
src/examples/Examples/MultiMap/Instances/MultiMap1.hs view
@@ -2,10 +2,10 @@ -- Copyright: © 2022–2023 Jonathan Knowles -- License: Apache-2.0 ----- An unlawful implementation of 'MultiMap', implemented in terms of 'Map' and--- 'Set'.+-- An __unlawful__ implementation of 'MultiMap', implemented in terms of 'Map'+-- and 'Set'. ----- This implementation has several subtle bugs.+-- This implementation has several subtle bugs. 💥 -- module Examples.MultiMap.Instances.MultiMap1 where @@ -20,10 +20,10 @@ import qualified Data.Set as Set import qualified Examples.MultiMap.Class as Class -newtype MultiMap k v = MultiMap (Map k (Set v))+newtype MultiMap1 k v = MultiMap (Map k (Set v)) deriving stock (Eq, Show) -instance (Ord k, Ord v) => Class.MultiMap MultiMap k v where+instance (Ord k, Ord v) => Class.MultiMap MultiMap1 k v where fromList = MultiMap . Map.fromList
src/examples/Examples/MultiMap/Instances/MultiMap2.hs view
@@ -2,7 +2,7 @@ -- Copyright: © 2022–2023 Jonathan Knowles -- License: Apache-2.0 ----- A lawful implementation of 'MultiMap', implemented in terms of 'Map' and+-- A __lawful__ implementation of 'MultiMap', implemented in terms of 'Map' and -- 'Set'. -- module Examples.MultiMap.Instances.MultiMap2 where@@ -19,10 +19,10 @@ import qualified Data.Set as Set import qualified Examples.MultiMap.Class as Class -newtype MultiMap k v = MultiMap (Map k (Set v))+newtype MultiMap2 k v = MultiMap (Map k (Set v)) deriving stock (Eq, Show) -instance (Ord k, Ord v) => Class.MultiMap MultiMap k v where+instance (Ord k, Ord v) => Class.MultiMap MultiMap2 k v where fromList = MultiMap . Map.fromListWith (<>) . filter ((/= mempty) . snd)
src/examples/Examples/MultiMap/Instances/MultiMap3.hs view
@@ -2,7 +2,7 @@ -- Copyright: © 2022–2023 Jonathan Knowles -- License: Apache-2.0 ----- A lawful implementation of 'MultiMap', implemented in terms of 'Map' and+-- A __lawful__ implementation of 'MultiMap', implemented in terms of 'Map' and -- 'NESet'. -- module Examples.MultiMap.Instances.MultiMap3 where@@ -22,10 +22,10 @@ import qualified Data.Set.NonEmpty as NESet import qualified Examples.MultiMap.Class as Class -newtype MultiMap k v = MultiMap (Map k (NESet v))+newtype MultiMap3 k v = MultiMap (Map k (NESet v)) deriving stock (Eq, Show) -instance (Ord k, Ord v) => Class.MultiMap MultiMap k v where+instance (Ord k, Ord v) => Class.MultiMap MultiMap3 k v where fromList = MultiMap
src/examples/Examples/MultiMap/Instances/MultiMap4.hs view
@@ -2,8 +2,8 @@ -- Copyright: © 2022–2023 Jonathan Knowles -- License: Apache-2.0 ----- A lawful implementation of 'MultiMap', implemented in terms of 'MonoidMap'--- and 'Set'.+-- A __lawful__ implementation of 'MultiMap', implemented in terms of+-- 'MonoidMap' and 'Set'. -- module Examples.MultiMap.Instances.MultiMap4 where @@ -18,10 +18,10 @@ import qualified Data.Set as Set import qualified Examples.MultiMap.Class as Class -newtype MultiMap k v = MultiMap (MonoidMap k (Set v))+newtype MultiMap4 k v = MultiMap (MonoidMap k (Set v)) deriving stock (Eq, Show) -instance (Ord k, Ord v) => Class.MultiMap MultiMap k v where+instance (Ord k, Ord v) => Class.MultiMap MultiMap4 k v where fromList = MultiMap . MonoidMap.fromListWith (<>)
src/internal/Data/MonoidMap/Internal.hs view
@@ -190,8 +190,7 @@ -- Type -------------------------------------------------------------------------------- -newtype MonoidMap k v = MonoidMap- { unMonoidMap :: Map k (NonNull v) }+newtype MonoidMap k v = MonoidMap (Map k (NonNull v)) deriving (Eq, Show, NFData, NoThunks) via Map k v deriving (Eq1, Show1, Foldable)
src/test/Examples/MultiMapSpec.hs view
@@ -25,6 +25,14 @@ ( Typeable, typeRep ) import Examples.MultiMap.Class ( MultiMap )+import Examples.MultiMap.Instances.MultiMap1+ ( MultiMap1 )+import Examples.MultiMap.Instances.MultiMap2+ ( MultiMap2 )+import Examples.MultiMap.Instances.MultiMap3+ ( MultiMap3 )+import Examples.MultiMap.Instances.MultiMap4+ ( MultiMap4 ) import Test.Hspec ( Spec, describe, it ) import Test.QuickCheck@@ -45,10 +53,6 @@ import qualified Data.Foldable as F import qualified Data.Set as Set import qualified Examples.MultiMap.Class as M-import qualified Examples.MultiMap.Instances.MultiMap1 as MultiMap1-import qualified Examples.MultiMap.Instances.MultiMap2 as MultiMap2-import qualified Examples.MultiMap.Instances.MultiMap3 as MultiMap3-import qualified Examples.MultiMap.Instances.MultiMap4 as MultiMap4 import qualified Test.QuickCheck as QC spec :: Spec@@ -57,11 +61,11 @@ -- Uncomment the following line to see property test failures for an -- unlawful implementation of 'MultiMap': --- -- specFor (Proxy @(MultiMap1.MultiMap Int Int))+ -- specFor (Proxy @(MultiMap1 Int Int)) - specFor (Proxy @(MultiMap2.MultiMap Int Int))- specFor (Proxy @(MultiMap3.MultiMap Int Int))- specFor (Proxy @(MultiMap4.MultiMap Int Int))+ specFor (Proxy @(MultiMap2 Int Int))+ specFor (Proxy @(MultiMap3 Int Int))+ specFor (Proxy @(MultiMap4 Int Int)) type Test m k v = ( Arbitrary k@@ -724,5 +728,5 @@ _preventRedundantImportErrors :: () _preventRedundantImportErrors = () where- _multiMap1 :: MultiMap1.MultiMap () ()+ _multiMap1 :: MultiMap1 () () _multiMap1 = M.empty