packages feed

int-multimap 0.2 → 0.2.1

raw patch · 3 files changed

+116/−4 lines, 3 filesdep +int-multimapdep +tastydep +tasty-hunitPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependencies added: int-multimap, tasty, tasty-hunit, tasty-quickcheck

API changes (from Hackage documentation)

+ IntMultimap: splitLookup :: Int -> IntMultiMap a -> (IntMultiMap a, Maybe (HashSet a), IntMultiMap a)
- IntMultimap: toList :: IntMultiMap b -> [(Int, b)]
+ IntMultimap: toList :: IntMultiMap a -> [(Int, a)]

Files

int-multimap.cabal view
@@ -1,7 +1,7 @@ name:   int-multimap version:-  0.2+  0.2.1 synopsis:   A data structure that associates each Int key with a set of values category:@@ -47,3 +47,24 @@     hashable >=1.2 && <2,     containers >=0.5.10 && <0.5.15,     unordered-containers >=0.2.8.0 && <0.3++test-suite test+  type:+    exitcode-stdio-1.0+  hs-source-dirs:+    test+  main-is:+    Main.hs+  default-extensions:+    Arrows, BangPatterns, ConstraintKinds, DataKinds, DefaultSignatures, DeriveDataTypeable, DeriveFoldable, DeriveFunctor, DeriveGeneric, DeriveTraversable, EmptyDataDecls, FlexibleContexts, FlexibleInstances, FunctionalDependencies, GADTs, GeneralizedNewtypeDeriving, LambdaCase, LiberalTypeSynonyms, MagicHash, MultiParamTypeClasses, MultiWayIf, NoImplicitPrelude, NoMonomorphismRestriction, OverloadedStrings, PatternGuards, ParallelListComp, QuasiQuotes, RankNTypes, RecordWildCards, ScopedTypeVariables, StandaloneDeriving, TemplateHaskell, TupleSections, TypeFamilies, TypeOperators, UnboxedTuples+  default-language:+    Haskell2010+  build-depends:+    int-multimap,+    base >=4.7 && <5,+    hashable >=1.2 && <2,+    containers >=0.5.10 && <0.5.15,+    unordered-containers >=0.2.8.0 && <0.3,+    tasty >=1.0.1 && <1.0.2,+    tasty-hunit >=0.9 && <0.11,+    tasty-quickcheck >=0.10 && <0.12
library/IntMultimap.hs view
@@ -25,7 +25,8 @@   keys,    -- * Filter-  split+  split,+  splitLookup ) where @@ -39,6 +40,7 @@ import Data.Hashable import Data.Functor import Data.List(length)+import Data.Maybe import Control.Monad  {-|@@ -64,7 +66,7 @@   toList = toList   fromList = fromList -toList :: IntMultiMap b -> [(Int, b)]+toList :: IntMultiMap a -> [(Int, a)] toList (IntMultiMap multiMap) = do   (key, hashSet) <- A.toList multiMap   fmap ((,) key) $ B.toList hashSet@@ -98,7 +100,9 @@  insert :: (Hashable a, Ord a) => Int -> a -> IntMultiMap a -> IntMultiMap a insert key value (IntMultiMap intMap) =-  IntMultiMap $ A.update (\hash -> Just $ B.insert value hash) key intMap+  IntMultiMap $ A.insertWith (f value) key (B.singleton value) intMap+    where+      f v new old = B.insert v old  delete :: (Hashable a, Eq a) => Int {-^ Key -} -> a -> IntMultiMap a -> IntMultiMap a delete key value (IntMultiMap intMap) =@@ -123,3 +127,8 @@ split key (IntMultiMap intMap) = (IntMultiMap oldMap, IntMultiMap newMap)   where     (oldMap, newMap) = A.split key intMap++splitLookup :: Int -> IntMultiMap a -> (IntMultiMap a, Maybe (B.HashSet a), IntMultiMap a)+splitLookup key (IntMultiMap intMap) = (IntMultiMap oldMap, elemHashSet, IntMultiMap newMap)+  where+    (oldMap, elemHashSet, newMap) = A.splitLookup key intMap
+ test/Main.hs view
@@ -0,0 +1,82 @@+module Main where++import Prelude hiding (first, second)+import Control.Arrow+import Test.Tasty+import Test.Tasty.Runners+import Test.Tasty.HUnit+import Test.Tasty.QuickCheck+-- import Test.QuickCheck.Instances+import qualified IntMultimap as A+import qualified Data.List as B+import Data.Maybe+import Data.Foldable as F+import qualified Data.HashSet as B++main =+  defaultMain $+  testGroup "All tests" $+  [+    testCase "Member" $ do+      let+        list = [(1, 'a'), (2, 'b'), (3, 'c'), (4, 'd')]+        multimap = A.fromList list+      assertEqual "" True $ A.member 3 multimap+      assertEqual "" False $ A.member 5 multimap+    ,+    testCase "Lists" $ do+      let+        list = [(1, 'a'), (2, 'b'), (3, 'c'), (4, 'd')]+        multimap = A.fromList list+      assertEqual "" list $ A.toList $ A.fromList list+      assertEqual "" multimap $ A.fromList $ A.toList multimap+    ,+    testCase "Conversions" $ do+      let+        list = [(1, 'a'), (2, 'b'), (3, 'c'), (4, 'd')]+        multimap = A.fromList list+      assertEqual "" (map fst list) $ A.keys multimap+      assertEqual "" (map snd list) $ A.elems multimap+    ,+    testCase "Filter" $ do+      let+        list = [(1, 'a'), (2, 'b'), (3, 'c'), (4, 'd')]+        multimap = A.fromList list+        (old, maybeElem, new) = A.splitLookup 3 multimap+      assertEqual "" ((A.toList old), [(3, 'c')] ++ A.toList new) (B.span (\(k,a) -> k < 3) list)+    ,+    testCase "Insert and Delete" $ do+      let+        list = [(1, 'a'), (2, 'b'), (4, 'd'), (5, 'e')]+        key = 3+        el = 'c'+        list2 = [(1, 'a'), (2, 'b'), (3, 'c'), (4, 'd'), (5, 'e')]+      assertEqual "" list2 $ A.toList $ A.insert key el $ A.fromList list+      assertEqual "" list $ A.toList $ A.delete key el $ A.fromList list2+    ,+    testCase "singleton and empty" $ do+      let+        list = [(1, 'a')]+        multimap = A.fromList list+      assertEqual "" True $ A.null A.empty+      assertEqual "" list $ A.toList $ A.singleton 1 'a'+      assertEqual "" (A.toList multimap) $ A.toList $ A.singleton 1 'a'+    ,+    testProperty "list to list(Int, String)" $ \ (list :: [(Int, String)]) ->+    (B.fromList list) === (B.fromList $ A.toList $ A.fromList list)+    ,+    testProperty "list to list(Int, Int)" $ \ (list :: [(Int, Int)]) ->+    (B.fromList list) === (B.fromList $ A.toList $ A.fromList list)+    ,+    testProperty "insert and delete" $ \ (list :: [(Int, Char)], key :: Int, value :: Char) ->+    (B.fromList list) === (B.fromList $ A.toList $ A.delete key value $ A.insert key value $ A.fromList list)+    ,+    testProperty "Mapping" $ \ (list :: [(Int, Int)]) ->+    (B.fromList $ map testFuncL list) === (B.fromList $ A.toList $ A.map testFunc $ A.fromList list)+  ]++testFunc :: (Show a) => a -> String+testFunc = show++testFuncL :: (Show a)  => (Int, a) -> (Int, String)+testFuncL (a, b) = (a, show b)