summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGabrielGonzalez <>2017-05-01 17:05:00 (GMT)
committerhdiff <hdiff@hdiff.luite.com>2017-05-01 17:05:00 (GMT)
commitceb9f3cdc6c0a54bf3b0092d0614931cade45574 (patch)
treedc10ed04b1d520eadcbcc8c8b19c29a8cc6b825e
parent49f33fc8a7e2ccc58af33b707b5fe2b6781d3c5a (diff)
version 1.2.51.2.5
-rw-r--r--CHANGELOG.md14
-rw-r--r--README.md2
-rw-r--r--bench/benchmarks.hs2
-rw-r--r--foldl.cabal4
-rw-r--r--src/Control/Foldl.hs72
5 files changed, 91 insertions, 3 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6218b78..ee4e55e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,17 @@
+1.2.5
+
+* Add support for folding new containers: `hashSet`, `map`, and `hashMap`
+* Add `prescan`/`postscan` which generalize `scan` to `Traversable` types
+
+1.2.4
+
+* Add `lazy` folds for `Text` and `ByteString`
+* Documentation fixes and improvements
+
+1.2.3
+
+* Add `lookup`
+
1.2.2
* Add numerically stable `mean`, `variance`, and `std` folds
diff --git a/README.md b/README.md
index 42e0b0c..316fd9a 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# `foldl` v1.2.4
+# `foldl` v1.2.5
Use this `foldl` library when you want to compute multiple folds over a
collection in one pass over the data without space leaks.
diff --git a/bench/benchmarks.hs b/bench/benchmarks.hs
index ee3731b..5f6d9cf 100644
--- a/bench/benchmarks.hs
+++ b/bench/benchmarks.hs
@@ -1,6 +1,6 @@
module Main (main) where
-import Control.Foldl
+import Control.Foldl hiding (map)
import Criterion.Main
import qualified Data.List
import Prelude hiding (length, sum)
diff --git a/foldl.cabal b/foldl.cabal
index b216dc1..1b08dab 100644
--- a/foldl.cabal
+++ b/foldl.cabal
@@ -1,5 +1,5 @@
Name: foldl
-Version: 1.2.4
+Version: 1.2.5
Cabal-Version: >=1.8.0.2
Build-Type: Simple
License: BSD3
@@ -33,6 +33,8 @@ Library
transformers >= 0.2.0.0 && < 0.6 ,
vector >= 0.7 && < 0.13,
containers < 0.6 ,
+ unordered-containers < 0.3 ,
+ hashable < 1.3 ,
contravariant < 1.5 ,
profunctors < 5.3 ,
comonad >= 4.0 && < 6
diff --git a/src/Control/Foldl.hs b/src/Control/Foldl.hs
index fe1dd56..872b39c 100644
--- a/src/Control/Foldl.hs
+++ b/src/Control/Foldl.hs
@@ -35,6 +35,7 @@
executables that use this library to further improve performance.
-}
+{-# LANGUAGE CPP #-}
{-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE RankNTypes #-}
@@ -49,6 +50,11 @@ module Control.Foldl (
, fold
, foldM
, scan
+#if MIN_VERSION_base(4,8,0)
+ , prescan
+ , postscan
+#else
+#endif
-- * Folds
, Control.Foldl.mconcat
@@ -94,6 +100,9 @@ module Control.Foldl (
, nub
, eqNub
, set
+ , hashSet
+ , map
+ , hashMap
, vector
-- * Utilities
@@ -139,6 +148,7 @@ import Data.Profunctor
import Data.Sequence ((|>))
import Data.Vector.Generic (Vector, Mutable)
import Data.Vector.Generic.Mutable (MVector)
+import Data.Hashable (Hashable)
import System.Random.MWC (GenIO, createSystemRandom, uniformR)
import Prelude hiding
( head
@@ -156,12 +166,16 @@ import Prelude hiding
, elem
, notElem
, lookup
+ , map
)
import qualified Data.Foldable as F
import qualified Data.List as List
import qualified Data.Sequence as Seq
import qualified Data.Set as Set
+import qualified Data.Map.Strict as Map
+import qualified Data.HashMap.Strict as HashMap
+import qualified Data.HashSet as HashSet
import qualified Data.Vector.Generic as V
import qualified Data.Vector.Generic.Mutable as M
@@ -461,6 +475,37 @@ scan (Fold step begin done) as = foldr cons nil as begin
cons a k x = done x:(k $! step x a)
{-# INLINE scan #-}
+#if MIN_VERSION_base(4,8,0)
+{-| Convert a `Fold` into a prescan for any `Traversable` type
+
+ \"Prescan\" means that the last element of the scan is not included
+-}
+prescan :: Traversable t => Fold a b -> t a -> t b
+prescan (Fold step begin done) as = bs
+ where
+ step' x a = (x', b)
+ where
+ x' = step x a
+ b = done x
+ (_, bs) = List.mapAccumL step' begin as
+{-# INLINE prescan #-}
+
+{-| Convert a `Fold` into a postscan for any `Traversable` type
+
+ \"Postscan\" means that the first element of the scan is not included
+-}
+postscan :: Traversable t => Fold a b -> t a -> t b
+postscan (Fold step begin done) as = bs
+ where
+ step' x a = (x', b)
+ where
+ x' = step x a
+ b = done x'
+ (_, bs) = List.mapAccumL step' begin as
+{-# INLINE postscan #-}
+#else
+#endif
+
-- | Fold all values within a container using 'mappend' and 'mempty'
mconcat :: Monoid a => Fold a a
mconcat = Fold mappend mempty id
@@ -824,6 +869,33 @@ set :: Ord a => Fold a (Set.Set a)
set = Fold (flip Set.insert) Set.empty id
{-# INLINABLE set #-}
+-- | Fold values into a hash-set
+hashSet :: (Eq a, Hashable a) => Fold a (HashSet.HashSet a)
+hashSet = Fold (flip HashSet.insert) HashSet.empty id
+{-# INLINABLE hashSet #-}
+
+{-|
+Fold pairs into a map.
+-}
+map :: Ord a => Fold (a, b) (Map.Map a b)
+map = Fold step begin done
+ where
+ begin = mempty
+ step m (k, v) = Map.insert k v m
+ done = id
+{-# INLINABLE map #-}
+
+{-|
+Fold pairs into a hash-map.
+-}
+hashMap :: (Eq a, Hashable a) => Fold (a, b) (HashMap.HashMap a b)
+hashMap = Fold step begin done
+ where
+ begin = mempty
+ step m (k, v) = HashMap.insert k v m
+ done = id
+{-# INLINABLE hashMap #-}
+
maxChunkSize :: Int
maxChunkSize = 8 * 1024 * 1024