packages feed

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 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