diff --git a/src/Streamly/Data/Fold.hs b/src/Streamly/Data/Fold.hs index 330a4209f..62cac778d 100644 --- a/src/Streamly/Data/Fold.hs +++ b/src/Streamly/Data/Fold.hs @@ -244,4 +244,3 @@ import Prelude span, splitAt, break, mapM) import Streamly.Internal.Data.Fold -import Streamly.Internal.Data.Fold.Types diff --git a/src/Streamly/Fold/Internal.hs b/src/Streamly/Fold/Internal.hs deleted file mode 100644 index d500080f5..000000000 --- a/src/Streamly/Fold/Internal.hs +++ /dev/null @@ -1,66 +0,0 @@ -{-# LANGUAGE BangPatterns #-} -{-# LANGUAGE CPP #-} -{-# LANGUAGE ExistentialQuantification #-} -{-# LANGUAGE FlexibleContexts #-} -{-# LANGUAGE RankNTypes #-} -{-# LANGUAGE RecordWildCards #-} -{-# LANGUAGE ScopedTypeVariables #-} - --- | --- Module : Streamly.Fold.Internal --- Copyright : (c) 2019 Composewell Technologies --- (c) 2013 Gabriel Gonzalez --- License : BSD3 --- Maintainer : harendra.kumar@gmail.com --- Stability : experimental --- Portability : GHC - -module Streamly.Fold.Internal - ( - rollingHash - , rollingHashWithSalt - -- , rollingHashFirstN - -- , rollingHashLastN - ) -where - -import Streamly.Internal.Data.Fold.Types (Fold(..)) - --- | Compute an 'Int' sized polynomial rolling hash --- --- > H = salt * k ^ n + c1 * k ^ (n - 1) + c2 * k ^ (n - 2) + ... + cn * k ^ 0 --- --- Where @c1@, @c2@, @cn@ are the elements in the input stream and @k@ is a --- constant. --- --- This hash is often used in Rabin-Karp string search algorithm. --- --- See https://en.wikipedia.org/wiki/Rolling_hash --- --- @since 0.7.0 -{-# INLINABLE rollingHashWithSalt #-} -rollingHashWithSalt :: (Monad m, Enum a) => Int -> Fold m a Int -rollingHashWithSalt salt = Fold step initial extract - where - k = 2891336453 - initial = return salt - step cksum a = return $ cksum * k + fromEnum a - extract = return - --- | A default salt used in the implementation of 'rollingHash'. -{-# INLINE defaultSalt #-} -defaultSalt :: Int -#if WORD_SIZE_IN_BITS == 64 -defaultSalt = 0xdc36d1615b7400a4 -#else -defaultSalt = 0x087fc72c -#endif - --- | Compute an 'Int' sized polynomial rolling hash of a stream. --- --- > rollingHash = rollingHashWithSalt defaultSalt --- --- @since 0.7.0 -{-# INLINABLE rollingHash #-} -rollingHash :: (Monad m, Enum a) => Fold m a Int -rollingHash = rollingHashWithSalt defaultSalt diff --git a/src/Streamly/Internal.hs b/src/Streamly/Internal.hs index ed34f1ac5..181d4d50e 100644 --- a/src/Streamly/Internal.hs +++ b/src/Streamly/Internal.hs @@ -55,5 +55,5 @@ import Streamly.Streams.Combinators (inspectMode) import Streamly.Unfold.Types (Unfold(..)) import Streamly.Unfold (fromList) -import Streamly.Fold.Internal +import Streamly.Internal.Data.Fold import Streamly.Internal.Data.Fold.Types diff --git a/src/Streamly/Internal/Data/Fold.hs b/src/Streamly/Internal/Data/Fold.hs index 294b3e579..65de1c768 100644 --- a/src/Streamly/Internal/Data/Fold.hs +++ b/src/Streamly/Internal/Data/Fold.hs @@ -50,6 +50,10 @@ module Streamly.Internal.Data.Fold , mean , variance , stdDev + , rollingHash + , rollingHashWithSalt + -- , rollingHashFirstN + -- , rollingHashLastN -- ** Full Folds (Monoidal) , mconcat @@ -486,6 +490,45 @@ variance = Fold step (return begin) (return . done) stdDev :: (Monad m, Floating a) => Fold m a a stdDev = sqrt variance +-- | Compute an 'Int' sized polynomial rolling hash +-- +-- > H = salt * k ^ n + c1 * k ^ (n - 1) + c2 * k ^ (n - 2) + ... + cn * k ^ 0 +-- +-- Where @c1@, @c2@, @cn@ are the elements in the input stream and @k@ is a +-- constant. +-- +-- This hash is often used in Rabin-Karp string search algorithm. +-- +-- See https://en.wikipedia.org/wiki/Rolling_hash +-- +-- @since 0.7.0 +{-# INLINABLE rollingHashWithSalt #-} +rollingHashWithSalt :: (Monad m, Enum a) => Int -> Fold m a Int +rollingHashWithSalt salt = Fold step initial extract + where + k = 2891336453 + initial = return salt + step cksum a = return $ cksum * k + fromEnum a + extract = return + +-- | A default salt used in the implementation of 'rollingHash'. +{-# INLINE defaultSalt #-} +defaultSalt :: Int +#if WORD_SIZE_IN_BITS == 64 +defaultSalt = 0xdc36d1615b7400a4 +#else +defaultSalt = 0x087fc72c +#endif + +-- | Compute an 'Int' sized polynomial rolling hash of a stream. +-- +-- > rollingHash = rollingHashWithSalt defaultSalt +-- +-- @since 0.7.0 +{-# INLINABLE rollingHash #-} +rollingHash :: (Monad m, Enum a) => Fold m a Int +rollingHash = rollingHashWithSalt defaultSalt + ------------------------------------------------------------------------------ -- Monoidal left folds ------------------------------------------------------------------------------ diff --git a/streamly.cabal b/streamly.cabal index c579e2985..eb9d1fded 100644 --- a/streamly.cabal +++ b/streamly.cabal @@ -288,7 +288,6 @@ library , Streamly.Unfold -- Folds - , Streamly.Fold.Internal , Streamly.Sink.Types , Streamly.Sink , Streamly.Pipe.Types