on master help sign in
Remove Applicative instance of Fold
commit171907e2b3f0deaba57443b99f38a83601905674 authorAdithya Kumar <adithya@composewell.com> dateThu 4 Mar 2021, 18:44 (6 years ago) parentd79dd95
6 files changed+16−142
Changelog.md+2−5 benchmark/Streamly/Benchmark/Data/Fold.hs+10−7 src/Streamly/Data/Fold.hs+1−1 src/Streamly/Internal/Data/Fold.hs+1−1 src/Streamly/Internal/Data/Fold/Types.hs−126 src/Streamly/Prelude.hs+2−2
Changelog.md+2−5
@@ -1,10 +1,5 @@
11## Unreleased
22
3−### Notice
4−
5−* In the next major release the behaviour of `<*>` for folds will be updated
6− from `teeWith` to `splitWith` to reflect it's similarity with parsers.
7−
83### Behavioral changes
94
105* `Streamly.Prelude.fold` can now terminate early without consuming the entire
@@ -31,6 +26,8 @@
3126 require an additional `MonadAsync` constraint. Several other
3227 functions that used these functions also now require the additional
3328 constraint.
29+* Remove `Applicative` instance of folds. Please use `teeWith` or the `Tee` type
30+ as an alternative to Fold applicative.
3431
3532### Enhancements
3633
benchmark/Streamly/Benchmark/Data/Fold.hs+10−7
@@ -70,7 +70,7 @@ takeLE value = IP.fold (FL.takeLE value FL.drain)
7070
7171{-# INLINE sequence_ #-}
7272sequence_ :: Monad m => Int -> Fold m a ()
73−sequence_ value = foldr f (pure ()) (Prelude.replicate value (FL.takeLE 1 FL.drain))
73+sequence_ value = foldr f (FL.yield ()) (Prelude.replicate value (FL.takeLE 1 FL.drain))
7474
7575 where
7676
@@ -118,10 +118,14 @@ split_ value =
118118teeSumLength :: Monad m => SerialT m Int -> m (Int, Int)
119119teeSumLength = IP.fold (FL.teeWith (,) FL.sum FL.length)
120120
121−{-# INLINE teeApplicative #-}
122−teeApplicative :: (Monad m, Ord a) => a -> SerialT m a -> m (Bool, Bool)
123−teeApplicative value =
124− IP.fold ((,) <$> FL.all (<= value) <*> FL.any (> value))
121+{-# INLINE teeAllAny #-}
122+teeAllAny :: (Monad m, Ord a) => a -> SerialT m a -> m (Bool, Bool)
123+teeAllAny value = IP.fold (FL.teeWith (,) all_ any_)
124+
125+ where
126+
127+ all_ = FL.all (<= value)
128+ any_ = FL.any (> value)
125129
126130{-# INLINE distribute #-}
127131distribute :: Monad m => SerialT m Int -> m [Int]
@@ -272,8 +276,7 @@ o_1_space_serial_composition value =
272276 [ bgroup
273277 "composition"
274278 [ benchIOSink value "splitWith (all, any)" $ splitAllAny value
275− , benchIOSink value "teeApplicative (all, any)"
276− $ teeApplicative value
279+ , benchIOSink value "tee (all, any)" $ teeAllAny value
277280 , benchIOSink value "many drain (takeLE 1)" many
278281 , benchIOSink value "tee (sum, length)" teeSumLength
279282 , benchIOSink value "distribute [sum, length]" distribute
src/Streamly/Data/Fold.hs+1−1
@@ -199,7 +199,7 @@ module Streamly.Data.Fold
199199 -- To compute the average of numbers in a stream without going through the
200200 -- stream twice:
201201 --
202− -- >>> let avg = (/) <$> Fold.sum <*> fmap fromIntegral Fold.length
202+ -- >>> let avg = Fold.teeWith (/) Fold.sum (fmap fromIntegral Fold.length)
203203 -- >>> Stream.fold avg (Stream.enumerateFromTo 1.0 100.0)
204204 -- 50.5
205205 --
src/Streamly/Internal/Data/Fold.hs+1−1
@@ -602,7 +602,7 @@ variance = mkAccum step begin done
602602-- @since 0.7.0
603603{-# INLINABLE stdDev #-}
604604stdDev :: (Monad m, Floating a) => Fold m a a
605−stdDev = sqrt variance
605+stdDev = sqrt <$> variance
606606
607607-- | Compute an 'Int' sized polynomial rolling hash
608608--
src/Streamly/Internal/Data/Fold/Types.hs−126
@@ -229,7 +229,6 @@ module Streamly.Internal.Data.Fold.Types
229229 )
230230where
231231
232−import Control.Applicative (liftA2)
233232import Control.Concurrent (threadDelay, forkIO, killThread)
234233import Control.Concurrent.MVar (MVar, newMVar, swapMVar, readMVar)
235234import Control.Exception (SomeException(..), catch, mask)
@@ -573,26 +572,6 @@ data GenericRunner sL sR bL bR
573572 | RunLeft !sL !bR
574573 | RunRight !bL !sR
575574
576−-- | The fold resulting from '<*>' distributes its input to both the argument
577−-- folds and combines their output using the supplied function.
578−--
579−-- __Note:__ The Applicative behaviour will change in the next major release.
580−--
581−instance Monad m => Applicative (Fold m a) where
582− {-# INLINE pure #-}
583− pure = yield
584−
585− -- | __Notice:__ In the next major release the behaviour of @<*>@ for folds
586− -- will be updated from 'teeWith' to 'splitWith' to reflect it's similarity
587− -- with parsers.
588− {-# INLINE (<*>) #-}
589− (<*>) = teeWith ($)
590−
591−#if MIN_VERSION_base(4,10,0)
592− {-# INLINE liftA2 #-}
593− liftA2 f x = (<*>) (fmap f x)
594−#endif
595−
596575-- | @teeWith k f1 f2@ distributes its input to both @f1@ and @f2@ until both
597576-- of them terminate and combines their output using @k@.
598577--
@@ -746,111 +725,6 @@ concatMap f (Fold stepa initiala extracta) = Fold stepc initialc extractc
746725 Partial s -> e s
747726 Done c -> return c
748727
749−-- | Combines the outputs of the folds (the type @b@) using their 'Semigroup'
750−-- instances.
751−instance (Semigroup b, Monad m) => Semigroup (Fold m a b) where
752− {-# INLINE (<>) #-}
753− (<>) = liftA2 (<>)
754−
755−-- | Combines the outputs of the folds (the type @b@) using their 'Monoid'
756−-- instances.
757−instance (Semigroup b, Monoid b, Monad m) => Monoid (Fold m a b) where
758− {-# INLINE mempty #-}
759− mempty = pure mempty
760−
761− {-# INLINE mappend #-}
762− mappend = (<>)
763−
764−-- | Combines the fold outputs (type @b@) using their 'Num' instances.
765−instance (Monad m, Num b) => Num (Fold m a b) where
766− {-# INLINE fromInteger #-}
767− fromInteger = pure . fromInteger
768−
769− {-# INLINE negate #-}
770− negate = fmap negate
771−
772− {-# INLINE abs #-}
773− abs = fmap abs
774−
775− {-# INLINE signum #-}
776− signum = fmap signum
777−
778− {-# INLINE (+) #-}
779− (+) = liftA2 (+)
780−
781− {-# INLINE (*) #-}
782− (*) = liftA2 (*)
783−
784− {-# INLINE (-) #-}
785− (-) = liftA2 (-)
786−
787−-- | Combines the fold outputs (type @b@) using their 'Fractional' instances.
788−instance (Monad m, Fractional b) => Fractional (Fold m a b) where
789− {-# INLINE fromRational #-}
790− fromRational = pure . fromRational
791−
792− {-# INLINE recip #-}
793− recip = fmap recip
794−
795− {-# INLINE (/) #-}
796− (/) = liftA2 (/)
797−
798−-- | Combines the fold outputs using their 'Floating' instances.
799−instance (Monad m, Floating b) => Floating (Fold m a b) where
800− {-# INLINE pi #-}
801− pi = pure pi
802−
803− {-# INLINE exp #-}
804− exp = fmap exp
805−
806− {-# INLINE sqrt #-}
807− sqrt = fmap sqrt
808−
809− {-# INLINE log #-}
810− log = fmap log
811−
812− {-# INLINE sin #-}
813− sin = fmap sin
814−
815− {-# INLINE tan #-}
816− tan = fmap tan
817−
818− {-# INLINE cos #-}
819− cos = fmap cos
820−
821− {-# INLINE asin #-}
822− asin = fmap asin
823−
824− {-# INLINE atan #-}
825− atan = fmap atan
826−
827− {-# INLINE acos #-}
828− acos = fmap acos
829−
830− {-# INLINE sinh #-}
831− sinh = fmap sinh
832−
833− {-# INLINE tanh #-}
834− tanh = fmap tanh
835−
836− {-# INLINE cosh #-}
837− cosh = fmap cosh
838−
839− {-# INLINE asinh #-}
840− asinh = fmap asinh
841−
842− {-# INLINE atanh #-}
843− atanh = fmap atanh
844−
845− {-# INLINE acosh #-}
846− acosh = fmap acosh
847−
848− {-# INLINE (**) #-}
849− (**) = liftA2 (**)
850−
851− {-# INLINE logBase #-}
852− logBase = liftA2 logBase
853−
854728------------------------------------------------------------------------------
855729-- Internal APIs
856730------------------------------------------------------------------------------
src/Streamly/Prelude.hs+2−2
@@ -997,12 +997,12 @@ import Streamly.Internal.Data.Stream.IsStream
997997-- running average of elements is no more than 10:
998998--
999999-- >>> import Data.Maybe (fromJust)
1000−-- >>> let avg = (/) <$> Fold.sum <*> fmap fromIntegral Fold.length
1000+-- >>> let avg = Fold.teeWith (/) Fold.sum (fmap fromIntegral Fold.length)
10011001-- >>> :{
10021002-- Stream.toList
10031003-- $ Stream.map (fromJust . fst)
10041004-- $ Stream.takeWhile (\(_,x) -> x <= 10)
1005−-- $ Stream.postscan ((,) <$> Fold.last <*> avg) (Stream.enumerateFromTo 1.0 100.0)
1005+-- $ Stream.postscan (Fold.tee Fold.last avg) (Stream.enumerateFromTo 1.0 100.0)
10061006-- :}
10071007-- [1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0,12.0,13.0,14.0,15.0,16.0,17.0,18.0,19.0]
10081008--