{-# LANGUAGE CPP #-}
{-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE FlexibleContexts #-}
module Streamly.Internal.Data.Fold.Types
( Fold (..)
, Fold2 (..)
, simplify
, toListRevF
, lmap
, lmapM
, lfilter
, lfilterM
, lcatMaybes
, ltake
, ltakeWhile
, lsessionsOf
, lchunksOf
, lchunksOf2
, duplicate
, initialize
, runStep
)
where
import Control.Applicative (liftA2)
import Control.Concurrent (threadDelay, forkIO, killThread)
import Control.Concurrent.MVar (MVar, newMVar, takeMVar, putMVar)
import Control.Exception (SomeException(..), catch, mask)
import Control.Monad (void)
import Control.Monad.Catch (throwM)
import Control.Monad.IO.Class (MonadIO(..))
import Control.Monad.Trans.Control (control)
import Data.Maybe (isJust, fromJust)
#if __GLASGOW_HASKELL__ < 808
import Data.Semigroup (Semigroup(..))
#endif
import Streamly.Internal.Data.Strict (Tuple'(..), Tuple3'(..), Either'(..))
import Streamly.Internal.Data.SVar (MonadAsync)
data Fold m a b =
forall s. Fold (s -> a -> m s) (m s) (s -> m b)
data Fold2 m c a b =
forall s. Fold2 (s -> a -> m s) (c -> m s) (s -> m b)
simplify :: Fold2 m c a b -> c -> Fold m a b
simplify :: forall (m :: * -> *) c a b. Fold2 m c a b -> c -> Fold m a b
simplify (Fold2 s -> a -> m s
step c -> m s
inject s -> m b
extract) c
c = forall (m :: * -> *) a b s.
(s -> a -> m s) -> m s -> (s -> m b) -> Fold m a b
Fold s -> a -> m s
step (c -> m s
inject c
c) s -> m b
extract
instance Functor m => Functor (Fold m a) where
{-# INLINE fmap #-}
fmap :: forall a b. (a -> b) -> Fold m a a -> Fold m a b
fmap a -> b
f (Fold s -> a -> m s
step m s
start s -> m a
done) = forall (m :: * -> *) a b s.
(s -> a -> m s) -> m s -> (s -> m b) -> Fold m a b
Fold s -> a -> m s
step m s
start s -> m b
done'
where
done' :: s -> m b
done' s
x = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
f forall a b. (a -> b) -> a -> b
$! s -> m a
done s
x
instance Applicative m => Applicative (Fold m a) where
{-# INLINE pure #-}
pure :: forall a. a -> Fold m a a
pure a
b = forall (m :: * -> *) a b s.
(s -> a -> m s) -> m s -> (s -> m b) -> Fold m a b
Fold (\() a
_ -> forall (f :: * -> *) a. Applicative f => a -> f a
pure ()) (forall (f :: * -> *) a. Applicative f => a -> f a
pure ()) (\() -> forall (f :: * -> *) a. Applicative f => a -> f a
pure a
b)
{-# INLINE (<*>) #-}
(Fold s -> a -> m s
stepL m s
beginL s -> m (a -> b)
doneL) <*> :: forall a b. Fold m a (a -> b) -> Fold m a a -> Fold m a b
<*> (Fold s -> a -> m s
stepR m s
beginR s -> m a
doneR) =
let step :: Tuple' s s -> a -> m (Tuple' s s)
step (Tuple' s
xL s
xR) a
a = forall a b. a -> b -> Tuple' a b
Tuple' forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> s -> a -> m s
stepL s
xL a
a forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> s -> a -> m s
stepR s
xR a
a
begin :: m (Tuple' s s)
begin = forall a b. a -> b -> Tuple' a b
Tuple' forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m s
beginL forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> m s
beginR
done :: Tuple' s s -> m b
done (Tuple' s
xL s
xR) = s -> m (a -> b)
doneL s
xL forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> s -> m a
doneR s
xR
in forall (m :: * -> *) a b s.
(s -> a -> m s) -> m s -> (s -> m b) -> Fold m a b
Fold Tuple' s s -> a -> m (Tuple' s s)
step m (Tuple' s s)
begin Tuple' s s -> m b
done
instance (Semigroup b, Monad m) => Semigroup (Fold m a b) where
{-# INLINE (<>) #-}
<> :: Fold m a b -> Fold m a b -> Fold m a b
(<>) = forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 forall a. Semigroup a => a -> a -> a
(<>)
instance (Semigroup b, Monoid b, Monad m) => Monoid (Fold m a b) where
{-# INLINE mempty #-}
mempty :: Fold m a b
mempty = forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a. Monoid a => a
mempty
{-# INLINE mappend #-}
mappend :: Fold m a b -> Fold m a b -> Fold m a b
mappend = forall a. Semigroup a => a -> a -> a
(<>)
instance (Monad m, Num b) => Num (Fold m a b) where
{-# INLINE fromInteger #-}
fromInteger :: Integer -> Fold m a b
fromInteger = forall (f :: * -> *) a. Applicative f => a -> f a
pure forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Num a => Integer -> a
fromInteger
{-# INLINE negate #-}
negate :: Fold m a b -> Fold m a b
negate = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a. Num a => a -> a
negate
{-# INLINE abs #-}
abs :: Fold m a b -> Fold m a b
abs = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a. Num a => a -> a
abs
{-# INLINE signum #-}
signum :: Fold m a b -> Fold m a b
signum = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a. Num a => a -> a
signum
{-# INLINE (+) #-}
+ :: Fold m a b -> Fold m a b -> Fold m a b
(+) = forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 forall a. Num a => a -> a -> a
(+)
{-# INLINE (*) #-}
* :: Fold m a b -> Fold m a b -> Fold m a b
(*) = forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 forall a. Num a => a -> a -> a
(*)
{-# INLINE (-) #-}
(-) = forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 (-)
instance (Monad m, Fractional b) => Fractional (Fold m a b) where
{-# INLINE fromRational #-}
fromRational :: Rational -> Fold m a b
fromRational = forall (f :: * -> *) a. Applicative f => a -> f a
pure forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Fractional a => Rational -> a
fromRational
{-# INLINE recip #-}
recip :: Fold m a b -> Fold m a b
recip = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a. Fractional a => a -> a
recip
{-# INLINE (/) #-}
/ :: Fold m a b -> Fold m a b -> Fold m a b
(/) = forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 forall a. Fractional a => a -> a -> a
(/)
instance (Monad m, Floating b) => Floating (Fold m a b) where
{-# INLINE pi #-}
pi :: Fold m a b
pi = forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a. Floating a => a
pi
{-# INLINE exp #-}
exp :: Fold m a b -> Fold m a b
exp = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a. Floating a => a -> a
exp
{-# INLINE sqrt #-}
sqrt :: Fold m a b -> Fold m a b
sqrt = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a. Floating a => a -> a
sqrt
{-# INLINE log #-}
log :: Fold m a b -> Fold m a b
log = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a. Floating a => a -> a
log
{-# INLINE sin #-}
sin :: Fold m a b -> Fold m a b
sin = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a. Floating a => a -> a
sin
{-# INLINE tan #-}
tan :: Fold m a b -> Fold m a b
tan = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a. Floating a => a -> a
tan
{-# INLINE cos #-}
cos :: Fold m a b -> Fold m a b
cos = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a. Floating a => a -> a
cos
{-# INLINE asin #-}
asin :: Fold m a b -> Fold m a b
asin = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a. Floating a => a -> a
asin
{-# INLINE atan #-}
atan :: Fold m a b -> Fold m a b
atan = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a. Floating a => a -> a
atan
{-# INLINE acos #-}
acos :: Fold m a b -> Fold m a b
acos = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a. Floating a => a -> a
acos
{-# INLINE sinh #-}
sinh :: Fold m a b -> Fold m a b
sinh = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a. Floating a => a -> a
sinh
{-# INLINE tanh #-}
tanh :: Fold m a b -> Fold m a b
tanh = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a. Floating a => a -> a
tanh
{-# INLINE cosh #-}
cosh :: Fold m a b -> Fold m a b
cosh = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a. Floating a => a -> a
cosh
{-# INLINE asinh #-}
asinh :: Fold m a b -> Fold m a b
asinh = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a. Floating a => a -> a
asinh
{-# INLINE atanh #-}
atanh :: Fold m a b -> Fold m a b
atanh = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a. Floating a => a -> a
atanh
{-# INLINE acosh #-}
acosh :: Fold m a b -> Fold m a b
acosh = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a. Floating a => a -> a
acosh
{-# INLINE (**) #-}
** :: Fold m a b -> Fold m a b -> Fold m a b
(**) = forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 forall a. Floating a => a -> a -> a
(**)
{-# INLINE logBase #-}
logBase :: Fold m a b -> Fold m a b -> Fold m a b
logBase = forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 forall a. Floating a => a -> a -> a
logBase
{-# INLINABLE toListRevF #-}
toListRevF :: Monad m => Fold m a [a]
toListRevF :: forall (m :: * -> *) a. Monad m => Fold m a [a]
toListRevF = forall (m :: * -> *) a b s.
(s -> a -> m s) -> m s -> (s -> m b) -> Fold m a b
Fold (\[a]
xs a
x -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ a
xforall a. a -> [a] -> [a]
:[a]
xs) (forall (m :: * -> *) a. Monad m => a -> m a
return []) forall (m :: * -> *) a. Monad m => a -> m a
return
{-# INLINABLE lmap #-}
lmap :: (a -> b) -> Fold m b r -> Fold m a r
lmap :: forall a b (m :: * -> *) r. (a -> b) -> Fold m b r -> Fold m a r
lmap a -> b
f (Fold s -> b -> m s
step m s
begin s -> m r
done) = forall (m :: * -> *) a b s.
(s -> a -> m s) -> m s -> (s -> m b) -> Fold m a b
Fold s -> a -> m s
step' m s
begin s -> m r
done
where
step' :: s -> a -> m s
step' s
x a
a = s -> b -> m s
step s
x (a -> b
f a
a)
{-# INLINABLE lmapM #-}
lmapM :: Monad m => (a -> m b) -> Fold m b r -> Fold m a r
lmapM :: forall (m :: * -> *) a b r.
Monad m =>
(a -> m b) -> Fold m b r -> Fold m a r
lmapM a -> m b
f (Fold s -> b -> m s
step m s
begin s -> m r
done) = forall (m :: * -> *) a b s.
(s -> a -> m s) -> m s -> (s -> m b) -> Fold m a b
Fold s -> a -> m s
step' m s
begin s -> m r
done
where
step' :: s -> a -> m s
step' s
x a
a = a -> m b
f a
a forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= s -> b -> m s
step s
x
{-# INLINABLE lfilter #-}
lfilter :: Monad m => (a -> Bool) -> Fold m a r -> Fold m a r
lfilter :: forall (m :: * -> *) a r.
Monad m =>
(a -> Bool) -> Fold m a r -> Fold m a r
lfilter a -> Bool
f (Fold s -> a -> m s
step m s
begin s -> m r
done) = forall (m :: * -> *) a b s.
(s -> a -> m s) -> m s -> (s -> m b) -> Fold m a b
Fold s -> a -> m s
step' m s
begin s -> m r
done
where
step' :: s -> a -> m s
step' s
x a
a = if a -> Bool
f a
a then s -> a -> m s
step s
x a
a else forall (m :: * -> *) a. Monad m => a -> m a
return s
x
{-# INLINABLE lfilterM #-}
lfilterM :: Monad m => (a -> m Bool) -> Fold m a r -> Fold m a r
lfilterM :: forall (m :: * -> *) a r.
Monad m =>
(a -> m Bool) -> Fold m a r -> Fold m a r
lfilterM a -> m Bool
f (Fold s -> a -> m s
step m s
begin s -> m r
done) = forall (m :: * -> *) a b s.
(s -> a -> m s) -> m s -> (s -> m b) -> Fold m a b
Fold s -> a -> m s
step' m s
begin s -> m r
done
where
step' :: s -> a -> m s
step' s
x a
a = do
Bool
use <- a -> m Bool
f a
a
if Bool
use then s -> a -> m s
step s
x a
a else forall (m :: * -> *) a. Monad m => a -> m a
return s
x
{-# INLINE lcatMaybes #-}
lcatMaybes :: Monad m => Fold m a b -> Fold m (Maybe a) b
lcatMaybes :: forall (m :: * -> *) a b.
Monad m =>
Fold m a b -> Fold m (Maybe a) b
lcatMaybes = forall (m :: * -> *) a r.
Monad m =>
(a -> Bool) -> Fold m a r -> Fold m a r
lfilter forall a. Maybe a -> Bool
isJust forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b (m :: * -> *) r. (a -> b) -> Fold m b r -> Fold m a r
lmap forall a. HasCallStack => Maybe a -> a
fromJust
{-# INLINABLE ltake #-}
ltake :: Monad m => Int -> Fold m a b -> Fold m a b
ltake :: forall (m :: * -> *) a b.
Monad m =>
Int -> Fold m a b -> Fold m a b
ltake Int
n (Fold s -> a -> m s
step m s
initial s -> m b
done) = forall (m :: * -> *) a b s.
(s -> a -> m s) -> m s -> (s -> m b) -> Fold m a b
Fold Tuple' Int s -> a -> m (Tuple' Int s)
step' m (Tuple' Int s)
initial' forall {a}. Tuple' a s -> m b
done'
where
initial' :: m (Tuple' Int s)
initial' = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall a b. a -> b -> Tuple' a b
Tuple' Int
0) m s
initial
step' :: Tuple' Int s -> a -> m (Tuple' Int s)
step' (Tuple' Int
i s
r) a
a = do
if Int
i forall a. Ord a => a -> a -> Bool
< Int
n
then do
s
res <- s -> a -> m s
step s
r a
a
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a b. a -> b -> Tuple' a b
Tuple' (Int
i forall a. Num a => a -> a -> a
+ Int
1) s
res
else forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a b. a -> b -> Tuple' a b
Tuple' Int
i s
r
done' :: Tuple' a s -> m b
done' (Tuple' a
_ s
r) = s -> m b
done s
r
{-# INLINABLE ltakeWhile #-}
ltakeWhile :: Monad m => (a -> Bool) -> Fold m a b -> Fold m a b
ltakeWhile :: forall (m :: * -> *) a r.
Monad m =>
(a -> Bool) -> Fold m a r -> Fold m a r
ltakeWhile a -> Bool
predicate (Fold s -> a -> m s
step m s
initial s -> m b
done) = forall (m :: * -> *) a b s.
(s -> a -> m s) -> m s -> (s -> m b) -> Fold m a b
Fold Either' s s -> a -> m (Either' s s)
step' forall {b}. m (Either' s b)
initial' Either' s s -> m b
done'
where
initial' :: m (Either' s b)
initial' = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a b. a -> Either' a b
Left' m s
initial
step' :: Either' s s -> a -> m (Either' s s)
step' (Left' s
r) a
a = do
if a -> Bool
predicate a
a
then forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a b. a -> Either' a b
Left' forall a b. (a -> b) -> a -> b
$ s -> a -> m s
step s
r a
a
else forall (m :: * -> *) a. Monad m => a -> m a
return (forall a b. b -> Either' a b
Right' s
r)
step' Either' s s
r a
_ = forall (m :: * -> *) a. Monad m => a -> m a
return Either' s s
r
done' :: Either' s s -> m b
done' (Left' s
r) = s -> m b
done s
r
done' (Right' s
r) = s -> m b
done s
r
{-# INLINABLE duplicate #-}
duplicate :: Applicative m => Fold m a b -> Fold m a (Fold m a b)
duplicate :: forall (m :: * -> *) a b.
Applicative m =>
Fold m a b -> Fold m a (Fold m a b)
duplicate (Fold s -> a -> m s
step m s
begin s -> m b
done) =
forall (m :: * -> *) a b s.
(s -> a -> m s) -> m s -> (s -> m b) -> Fold m a b
Fold s -> a -> m s
step m s
begin (\s
x -> forall (f :: * -> *) a. Applicative f => a -> f a
pure (forall (m :: * -> *) a b s.
(s -> a -> m s) -> m s -> (s -> m b) -> Fold m a b
Fold s -> a -> m s
step (forall (f :: * -> *) a. Applicative f => a -> f a
pure s
x) s -> m b
done))
{-# INLINABLE initialize #-}
initialize :: Monad m => Fold m a b -> m (Fold m a b)
initialize :: forall (m :: * -> *) a b. Monad m => Fold m a b -> m (Fold m a b)
initialize (Fold s -> a -> m s
step m s
initial s -> m b
extract) = do
s
i <- m s
initial
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a b s.
(s -> a -> m s) -> m s -> (s -> m b) -> Fold m a b
Fold s -> a -> m s
step (forall (m :: * -> *) a. Monad m => a -> m a
return s
i) s -> m b
extract
{-# INLINABLE runStep #-}
runStep :: Monad m => Fold m a b -> a -> m (Fold m a b)
runStep :: forall (m :: * -> *) a b.
Monad m =>
Fold m a b -> a -> m (Fold m a b)
runStep (Fold s -> a -> m s
step m s
initial s -> m b
extract) a
a = do
s
i <- m s
initial
s
r <- s -> a -> m s
step s
i a
a
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ (forall (m :: * -> *) a b s.
(s -> a -> m s) -> m s -> (s -> m b) -> Fold m a b
Fold s -> a -> m s
step (forall (m :: * -> *) a. Monad m => a -> m a
return s
r) s -> m b
extract)
{-# INLINE lchunksOf #-}
lchunksOf :: Monad m => Int -> Fold m a b -> Fold m b c -> Fold m a c
lchunksOf :: forall (m :: * -> *) a b c.
Monad m =>
Int -> Fold m a b -> Fold m b c -> Fold m a c
lchunksOf Int
n (Fold s -> a -> m s
step1 m s
initial1 s -> m b
extract1) (Fold s -> b -> m s
step2 m s
initial2 s -> m c
extract2) =
forall (m :: * -> *) a b s.
(s -> a -> m s) -> m s -> (s -> m b) -> Fold m a b
Fold Tuple3' Int s s -> a -> m (Tuple3' Int s s)
step' m (Tuple3' Int s s)
initial' forall {a}. Tuple3' a s s -> m c
extract'
where
initial' :: m (Tuple3' Int s s)
initial' = (forall a b c. a -> b -> c -> Tuple3' a b c
Tuple3' Int
0) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m s
initial1 forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> m s
initial2
step' :: Tuple3' Int s s -> a -> m (Tuple3' Int s s)
step' (Tuple3' Int
i s
r1 s
r2) a
a = do
if Int
i forall a. Ord a => a -> a -> Bool
< Int
n
then do
s
res <- s -> a -> m s
step1 s
r1 a
a
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a b c. a -> b -> c -> Tuple3' a b c
Tuple3' (Int
i forall a. Num a => a -> a -> a
+ Int
1) s
res s
r2
else do
b
res <- s -> m b
extract1 s
r1
s
acc2 <- s -> b -> m s
step2 s
r2 b
res
s
i1 <- m s
initial1
s
acc1 <- s -> a -> m s
step1 s
i1 a
a
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a b c. a -> b -> c -> Tuple3' a b c
Tuple3' Int
1 s
acc1 s
acc2
extract' :: Tuple3' a s s -> m c
extract' (Tuple3' a
_ s
r1 s
r2) = do
b
res <- s -> m b
extract1 s
r1
s
acc2 <- s -> b -> m s
step2 s
r2 b
res
s -> m c
extract2 s
acc2
{-# INLINE lchunksOf2 #-}
lchunksOf2 :: Monad m => Int -> Fold m a b -> Fold2 m x b c -> Fold2 m x a c
lchunksOf2 :: forall (m :: * -> *) a b x c.
Monad m =>
Int -> Fold m a b -> Fold2 m x b c -> Fold2 m x a c
lchunksOf2 Int
n (Fold s -> a -> m s
step1 m s
initial1 s -> m b
extract1) (Fold2 s -> b -> m s
step2 x -> m s
inject2 s -> m c
extract2) =
forall (m :: * -> *) c a b s.
(s -> a -> m s) -> (c -> m s) -> (s -> m b) -> Fold2 m c a b
Fold2 Tuple3' Int s s -> a -> m (Tuple3' Int s s)
step' forall {a}. Num a => x -> m (Tuple3' a s s)
inject' forall {a}. Tuple3' a s s -> m c
extract'
where
inject' :: x -> m (Tuple3' a s s)
inject' x
x = (forall a b c. a -> b -> c -> Tuple3' a b c
Tuple3' a
0) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m s
initial1 forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> x -> m s
inject2 x
x
step' :: Tuple3' Int s s -> a -> m (Tuple3' Int s s)
step' (Tuple3' Int
i s
r1 s
r2) a
a = do
if Int
i forall a. Ord a => a -> a -> Bool
< Int
n
then do
s
res <- s -> a -> m s
step1 s
r1 a
a
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a b c. a -> b -> c -> Tuple3' a b c
Tuple3' (Int
i forall a. Num a => a -> a -> a
+ Int
1) s
res s
r2
else do
b
res <- s -> m b
extract1 s
r1
s
acc2 <- s -> b -> m s
step2 s
r2 b
res
s
i1 <- m s
initial1
s
acc1 <- s -> a -> m s
step1 s
i1 a
a
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a b c. a -> b -> c -> Tuple3' a b c
Tuple3' Int
1 s
acc1 s
acc2
extract' :: Tuple3' a s s -> m c
extract' (Tuple3' a
_ s
r1 s
r2) = do
b
res <- s -> m b
extract1 s
r1
s
acc2 <- s -> b -> m s
step2 s
r2 b
res
s -> m c
extract2 s
acc2
{-# INLINE lsessionsOf #-}
lsessionsOf :: MonadAsync m => Double -> Fold m a b -> Fold m b c -> Fold m a c
lsessionsOf :: forall (m :: * -> *) a b c.
MonadAsync m =>
Double -> Fold m a b -> Fold m b c -> Fold m a c
lsessionsOf Double
n (Fold s -> a -> m s
step1 m s
initial1 s -> m b
extract1) (Fold s -> b -> m s
step2 m s
initial2 s -> m c
extract2) =
forall (m :: * -> *) a b s.
(s -> a -> m s) -> m s -> (s -> m b) -> Fold m a b
Fold forall {a} {c}.
Tuple3' a (MVar s) c -> a -> m (Tuple3' a (MVar s) c)
step' m (Tuple3' ThreadId (MVar s) (MVar (Either SomeException s)))
initial' forall {e} {b}.
Exception e =>
Tuple3' ThreadId b (MVar (Either e s)) -> m c
extract'
where
initial' :: m (Tuple3' ThreadId (MVar s) (MVar (Either SomeException s)))
initial' = do
s
i1 <- m s
initial1
s
i2 <- m s
initial2
MVar s
mv1 <- forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall a. a -> IO (MVar a)
newMVar s
i1
MVar (Either SomeException s)
mv2 <- forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall a. a -> IO (MVar a)
newMVar (forall a b. b -> Either a b
Right s
i2)
ThreadId
t <- forall (b :: * -> *) (m :: * -> *) a.
MonadBaseControl b m =>
(RunInBase m b -> b (StM m a)) -> m a
control forall a b. (a -> b) -> a -> b
$ \RunInBase m IO
run ->
forall b. ((forall a. IO a -> IO a) -> IO b) -> IO b
mask forall a b. (a -> b) -> a -> b
$ \forall a. IO a -> IO a
restore -> do
ThreadId
tid <- IO () -> IO ThreadId
forkIO forall a b. (a -> b) -> a -> b
$ forall e a. Exception e => IO a -> (e -> IO a) -> IO a
catch (forall a. IO a -> IO a
restore forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a. Functor f => f a -> f ()
void forall a b. (a -> b) -> a -> b
$ RunInBase m IO
run (forall {a} {b}. MVar s -> MVar (Either a s) -> m b
timerThread MVar s
mv1 MVar (Either SomeException s)
mv2))
(forall a. MVar (Either SomeException a) -> SomeException -> IO ()
handleChildException MVar (Either SomeException s)
mv2)
RunInBase m IO
run (forall (m :: * -> *) a. Monad m => a -> m a
return ThreadId
tid)
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a b c. a -> b -> c -> Tuple3' a b c
Tuple3' ThreadId
t MVar s
mv1 MVar (Either SomeException s)
mv2
step' :: Tuple3' a (MVar s) c -> a -> m (Tuple3' a (MVar s) c)
step' acc :: Tuple3' a (MVar s) c
acc@(Tuple3' a
_ MVar s
mv1 c
_) a
a = do
s
r1 <- forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall a. MVar a -> IO a
takeMVar MVar s
mv1
s
res <- s -> a -> m s
step1 s
r1 a
a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall a. MVar a -> a -> IO ()
putMVar MVar s
mv1 s
res
forall (m :: * -> *) a. Monad m => a -> m a
return Tuple3' a (MVar s) c
acc
extract' :: Tuple3' ThreadId b (MVar (Either e s)) -> m c
extract' (Tuple3' ThreadId
tid b
_ MVar (Either e s)
mv2) = do
Either e s
r2 <- forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall a. MVar a -> IO a
takeMVar MVar (Either e s)
mv2
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ ThreadId -> IO ()
killThread ThreadId
tid
case Either e s
r2 of
Left e
e -> forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM e
e
Right s
x -> s -> m c
extract2 s
x
timerThread :: MVar s -> MVar (Either a s) -> m b
timerThread MVar s
mv1 MVar (Either a s)
mv2 = do
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ Int -> IO ()
threadDelay (forall a b. (RealFrac a, Integral b) => a -> b
round forall a b. (a -> b) -> a -> b
$ Double
n forall a. Num a => a -> a -> a
* Double
1000000)
s
r1 <- forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall a. MVar a -> IO a
takeMVar MVar s
mv1
s
i1 <- m s
initial1
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall a. MVar a -> a -> IO ()
putMVar MVar s
mv1 s
i1
b
res1 <- s -> m b
extract1 s
r1
Either a s
r2 <- forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall a. MVar a -> IO a
takeMVar MVar (Either a s)
mv2
Either a s
res <- case Either a s
r2 of
Left a
_ -> forall (m :: * -> *) a. Monad m => a -> m a
return Either a s
r2
Right s
x -> forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a b. b -> Either a b
Right forall a b. (a -> b) -> a -> b
$ s -> b -> m s
step2 s
x b
res1
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall a. MVar a -> a -> IO ()
putMVar MVar (Either a s)
mv2 Either a s
res
MVar s -> MVar (Either a s) -> m b
timerThread MVar s
mv1 MVar (Either a s)
mv2
handleChildException ::
MVar (Either SomeException a) -> SomeException -> IO ()
handleChildException :: forall a. MVar (Either SomeException a) -> SomeException -> IO ()
handleChildException MVar (Either SomeException a)
mv2 SomeException
e = do
Either SomeException a
r2 <- forall a. MVar a -> IO a
takeMVar MVar (Either SomeException a)
mv2
let r :: Either SomeException a
r = case Either SomeException a
r2 of
Left SomeException
_ -> Either SomeException a
r2
Right a
_ -> forall a b. a -> Either a b
Left SomeException
e
forall a. MVar a -> a -> IO ()
putMVar MVar (Either SomeException a)
mv2 Either SomeException a
r