universum 1.0.1 → 1.0.2
raw patch · 5 files changed
+113/−12 lines, 5 filesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
+ Universum.Container.Class: class ToPairs t where {
+ Universum.Container.Class: elems :: ToPairs t => t -> [Val t]
+ Universum.Container.Class: instance Universum.Container.Class.ToPairs (Data.HashMap.Base.HashMap k v)
+ Universum.Container.Class: instance Universum.Container.Class.ToPairs (Data.IntMap.Internal.IntMap v)
+ Universum.Container.Class: instance Universum.Container.Class.ToPairs (Data.Map.Internal.Map k v)
+ Universum.Container.Class: keys :: ToPairs t => t -> [Key t]
+ Universum.Container.Class: toPairs :: ToPairs t => t -> [(Key t, Val t)]
- Universum.Container.Class: foldl' :: (Container t, Foldable f, t ~ f a, Element t ~ a) => (b -> Element t -> b) -> b -> t -> b
+ Universum.Container.Class: foldl' :: (Container t, Foldable f, t ~ f a, Element t ~ a) => (Element t -> b -> b) -> b -> t -> b
Files
- CHANGES.md +8/−0
- README.md +2/−0
- benchmark/Main.hs +15/−2
- src/Universum/Container/Class.hs +87/−9
- universum.cabal +1/−1
CHANGES.md view
@@ -1,3 +1,11 @@+1.0.2+=====++* [#91](https://github.com/serokell/universum/issues/91):+ Change argument order of `foldl'`.+* [#97](https://github.com/serokell/universum/issues/97):+ Add `ToPairs` type class with the ability to have list of pairs.+ 1.0.1 =====
README.md view
@@ -144,6 +144,7 @@ * As a consequence of previous point, some functions like `traverse_`, `forM_`, `sequenceA_`, etc. are generalized over `Container` type classes. * `error` takes `Text`.+* `foldl'` takes a function with its arguments flipped compared with the `base` version. Things that you were already using, but now you don't have to import them explicitly@@ -277,6 +278,7 @@ for creating singleton containers. Even monomorhpic ones like `Text`. * `evaluateWHNF` and `evaluateNF` functions as clearer and lifted aliases for `evaluate` and `evaluate . force`.+* `ToPairs` type class for data types that can be converted to list of pairs. License -------
benchmark/Main.hs view
@@ -15,11 +15,12 @@ import Universum.VarArg ((...)) import qualified Data.Foldable as Foldable (elem)-import qualified Data.HashSet as HashSet (fromList)+import qualified Data.HashSet as HashSet (fromList, insert)+import qualified Data.List as List (foldl') import qualified Data.List.NonEmpty as NonEmpty import qualified Data.Set as Set (fromList) import qualified Data.Text as T-import qualified Universum.Container as Container (elem)+import qualified Universum.Container as Container (elem, foldl') main :: IO () main = defaultMain@@ -30,6 +31,7 @@ , bgroupSuperComposition , bgroupConcatMap , bgroupMember+ , bgroupFold ] bgroupList :: forall a .@@ -166,4 +168,15 @@ , bench "Set/elem" $ whnf (Container.elem sample) listSet , bench "HashSet/Foldable" $ whnf (Foldable.elem sample) listHashSet , bench "HashSet/elem" $ whnf (Container.elem sample) listHashSet+ ]++-- | Checks that 'foldl'' is implemented efficiently for 'Universum.List'+bgroupFold :: Benchmark+bgroupFold = do+ let testList = [1..100000] :: [Int]+ let universumFoldl' = Container.foldl' HashSet.insert mempty+ let ghcFoldl' = List.foldl' (\hashSet element -> + HashSet.insert element hashSet) mempty+ bgroup "foldl'" [ bench "universum" $ nf universumFoldl' testList+ , bench "base" $ nf ghcFoldl' testList ]
src/Universum/Container/Class.hs view
@@ -22,6 +22,7 @@ module Universum.Container.Class ( -- * Foldable-like classes and methods ToList (..)+ , ToPairs (..) , Container (..) , sum@@ -94,7 +95,6 @@ ElementDefault (f a) = a -- | Type class for data types that can be converted to List.--- Fully compatible with 'Foldable'. -- Contains very small and safe subset of 'Foldable' functions. -- -- You can define 'Tolist' by just defining 'toList' function.@@ -205,6 +205,84 @@ instance ToList (Vector a) ----------------------------------------------------------------------------+-- ToPairs+----------------------------------------------------------------------------++{- | Type class for data types that can be converted to List of Pairs.+ You can define 'ToPairs' by just defining 'toPairs' function.++ But the following laws should be met:++@+'toPairs' m ≡ 'zip' ('keys' m) ('elems' m)+'keys' ≡ 'map' 'fst' . 'toPairs'+'elems' ≡ 'map' 'snd' . 'toPairs'+@++-}+class ToPairs t where+ {-# MINIMAL toPairs #-}+ -- | Type of keys of the mapping.+ type Key t :: *+ -- | Type of value of the mapping.+ type Val t :: *++ -- | Converts the structure to the list of the key-value pairs.+ -- >>> import qualified Data.HashMap as HashMap+ -- >>> toPairs (HashMap.fromList [('a', "xxx"), ('b', "yyy")])+ -- [('a', "xxx"), ('b', "yyy")]+ toPairs :: t -> [(Key t, Val t)]++ -- | Converts the structure to the list of the keys.+ --+ -- >>> keys (HashMap.fromList [('a', "xxx"), ('b', "yyy")])+ -- "ab"+ keys :: t -> [Key t]+ keys = map fst . toPairs+ {-# INLINE keys #-}++ -- | Converts the structure to the list of the values.+ --+ -- >>> elems (HashMap.fromList [('a', "xxx"), ('b', "yyy")])+ -- ["xxx", "yyy"]+ elems :: t -> [Val t]+ elems = map snd . toPairs+ {-# INLINE elems #-}++-- Instances++instance ToPairs (HashMap k v) where+ type Key (HashMap k v) = k+ type Val (HashMap k v) = v+ toPairs = HM.toList+ {-# INLINE toPairs #-}+ keys = HM.keys+ {-# INLINE keys #-}+ elems = HM.elems+ {-# INLINE elems #-}++instance ToPairs (IntMap v) where+ type Key (IntMap v) = Int+ type Val (IntMap v) = v+ toPairs = IM.toList+ {-# INLINE toPairs #-}+ keys = IM.keys+ {-# INLINE keys #-}+ elems = IM.elems+ {-# INLINE elems #-}++instance ToPairs (Map k v) where+ type Key (Map k v) = k+ type Val (Map k v) = v+ toPairs = M.toList+ {-# INLINE toPairs #-}+ keys = M.keys+ {-# INLINE keys #-}+ elems = M.elems+ {-# INLINE elems #-}+++---------------------------------------------------------------------------- -- Additional operations that don't make much sense for e.g. Maybe ---------------------------------------------------------------------------- @@ -226,9 +304,9 @@ foldl = Foldable.foldl {-# INLINE foldl #-} - foldl' :: (b -> Element t -> b) -> b -> t -> b- default foldl' :: (Foldable f, t ~ f a, Element t ~ a) => (b -> Element t -> b) -> b -> t -> b- foldl' = Foldable.foldl'+ foldl' :: (Element t -> b -> b) -> b -> t -> b+ default foldl' :: (Foldable f, t ~ f a, Element t ~ a) => (Element t -> b -> b) -> b -> t -> b+ foldl' f = Foldable.foldl' (flip f) {-# INLINE foldl' #-} length :: t -> Int@@ -334,7 +412,7 @@ {-# INLINE foldr #-} foldl = T.foldl {-# INLINE foldl #-}- foldl' = T.foldl'+ foldl' f = T.foldl' (flip f) {-# INLINE foldl' #-} foldr1 = T.foldr1 {-# INLINE foldr1 #-}@@ -362,7 +440,7 @@ {-# INLINE foldr #-} foldl = TL.foldl {-# INLINE foldl #-}- foldl' = TL.foldl'+ foldl' f = TL.foldl' (flip f) {-# INLINE foldl' #-} foldr1 = TL.foldr1 {-# INLINE foldr1 #-}@@ -391,7 +469,7 @@ {-# INLINE foldr #-} foldl = BS.foldl {-# INLINE foldl #-}- foldl' = BS.foldl'+ foldl' f = BS.foldl' (flip f) {-# INLINE foldl' #-} foldr1 = BS.foldr1 {-# INLINE foldr1 #-}@@ -421,7 +499,7 @@ {-# INLINE foldr #-} foldl = BSL.foldl {-# INLINE foldl #-}- foldl' = BSL.foldl'+ foldl' f = BSL.foldl' (flip f) {-# INLINE foldl' #-} foldr1 = BSL.foldr1 {-# INLINE foldr1 #-}@@ -451,7 +529,7 @@ {-# INLINE foldr #-} foldl = IS.foldl {-# INLINE foldl #-}- foldl' = IS.foldl'+ foldl' f = IS.foldl' (flip f) {-# INLINE foldl' #-} length = IS.size {-# INLINE length #-}
universum.cabal view
@@ -1,5 +1,5 @@ name: universum-version: 1.0.1+version: 1.0.2 cabal-version: >=1.18 build-type: Simple license: MIT