{-# LANGUAGE GADTs #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Data.Machine.Fanout (fanout, fanoutSteps) where
import Data.List.NonEmpty (NonEmpty (..))
import Data.Machine
import Data.Semigroup (Semigroup (sconcat))
continue :: ([b] -> r) -> [(a -> b, b)] -> Step (Is a) o r
continue :: forall b r a o. ([b] -> r) -> [(a -> b, b)] -> Step (Is a) o r
continue [b] -> r
_ [] = Step (Is a) o r
forall (k :: * -> *) o r. Step k o r
Stop
continue [b] -> r
f [(a -> b, b)]
ws = (a -> r) -> Is a a -> r -> Step (Is a) o r
forall (k :: * -> *) o r t. (t -> r) -> k t -> r -> Step k o r
Await ([b] -> r
f ([b] -> r) -> (a -> [b]) -> a -> r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((a -> b, b) -> a -> b) -> [(a -> b, b)] -> a -> [b]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse (a -> b, b) -> a -> b
forall a b. (a, b) -> a
fst [(a -> b, b)]
ws) Is a a
forall a. Is a a
Refl ([b] -> r
f ([b] -> r) -> [b] -> r
forall a b. (a -> b) -> a -> b
$ ((a -> b, b) -> b) -> [(a -> b, b)] -> [b]
forall a b. (a -> b) -> [a] -> [b]
map (a -> b, b) -> b
forall a b. (a, b) -> b
snd [(a -> b, b)]
ws)
semigroupDlist :: Semigroup a => ([a] -> [a]) -> Maybe a
semigroupDlist :: forall a. Semigroup a => ([a] -> [a]) -> Maybe a
semigroupDlist [a] -> [a]
f = case [a] -> [a]
f [] of
[] -> Maybe a
forall a. Maybe a
Nothing
a
x:[a]
xs -> a -> Maybe a
forall a. a -> Maybe a
Just (a -> Maybe a) -> a -> Maybe a
forall a b. (a -> b) -> a -> b
$ NonEmpty a -> a
forall a. Semigroup a => NonEmpty a -> a
sconcat (a
xa -> [a] -> NonEmpty a
forall a. a -> [a] -> NonEmpty a
:|[a]
xs)
fanout :: forall m a r. (Monad m, Semigroup r)
=> [ProcessT m a r] -> ProcessT m a r
fanout :: forall (m :: * -> *) a r.
(Monad m, Semigroup r) =>
[ProcessT m a r] -> ProcessT m a r
fanout = m (Step (Is a) r (MachineT m (Is a) r)) -> MachineT m (Is a) r
forall (m :: * -> *) (k :: * -> *) o.
m (Step k o (MachineT m k o)) -> MachineT m k o
MachineT (m (Step (Is a) r (MachineT m (Is a) r)) -> MachineT m (Is a) r)
-> ([MachineT m (Is a) r]
-> m (Step (Is a) r (MachineT m (Is a) r)))
-> [MachineT m (Is a) r]
-> MachineT m (Is a) r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([(a -> MachineT m (Is a) r, MachineT m (Is a) r)]
-> [(a -> MachineT m (Is a) r, MachineT m (Is a) r)])
-> ([r] -> [r])
-> [MachineT m (Is a) r]
-> m (Step (Is a) r (MachineT m (Is a) r))
go [(a -> MachineT m (Is a) r, MachineT m (Is a) r)]
-> [(a -> MachineT m (Is a) r, MachineT m (Is a) r)]
forall a. a -> a
id [r] -> [r]
forall a. a -> a
id
where
go :: ([(a -> ProcessT m a r, ProcessT m a r)]
-> [(a -> ProcessT m a r, ProcessT m a r)])
-> ([r] -> [r])
-> [ProcessT m a r]
-> m (Step (Is a) r (ProcessT m a r))
go :: ([(a -> MachineT m (Is a) r, MachineT m (Is a) r)]
-> [(a -> MachineT m (Is a) r, MachineT m (Is a) r)])
-> ([r] -> [r])
-> [MachineT m (Is a) r]
-> m (Step (Is a) r (MachineT m (Is a) r))
go [(a -> MachineT m (Is a) r, MachineT m (Is a) r)]
-> [(a -> MachineT m (Is a) r, MachineT m (Is a) r)]
waiting [r] -> [r]
acc [] = case [(a -> MachineT m (Is a) r, MachineT m (Is a) r)]
-> [(a -> MachineT m (Is a) r, MachineT m (Is a) r)]
waiting [] of
[(a -> MachineT m (Is a) r, MachineT m (Is a) r)]
ws -> Step (Is a) r (MachineT m (Is a) r)
-> m (Step (Is a) r (MachineT m (Is a) r))
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Step (Is a) r (MachineT m (Is a) r)
-> m (Step (Is a) r (MachineT m (Is a) r)))
-> (Maybe r -> Step (Is a) r (MachineT m (Is a) r))
-> Maybe r
-> m (Step (Is a) r (MachineT m (Is a) r))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Step (Is a) r (MachineT m (Is a) r)
-> (r -> Step (Is a) r (MachineT m (Is a) r))
-> Maybe r
-> Step (Is a) r (MachineT m (Is a) r)
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Step (Is a) r (MachineT m (Is a) r)
k (\r
x -> r -> MachineT m (Is a) r -> Step (Is a) r (MachineT m (Is a) r)
forall (k :: * -> *) o r. o -> r -> Step k o r
Yield r
x (MachineT m (Is a) r -> Step (Is a) r (MachineT m (Is a) r))
-> MachineT m (Is a) r -> Step (Is a) r (MachineT m (Is a) r)
forall a b. (a -> b) -> a -> b
$ Step (Is a) r (MachineT m (Is a) r) -> MachineT m (Is a) r
forall (m :: * -> *) (k :: * -> *) o.
Monad m =>
Step k o (MachineT m k o) -> MachineT m k o
encased Step (Is a) r (MachineT m (Is a) r)
k) (Maybe r -> m (Step (Is a) r (MachineT m (Is a) r)))
-> Maybe r -> m (Step (Is a) r (MachineT m (Is a) r))
forall a b. (a -> b) -> a -> b
$ ([r] -> [r]) -> Maybe r
forall a. Semigroup a => ([a] -> [a]) -> Maybe a
semigroupDlist [r] -> [r]
acc
where k :: Step (Is a) r (MachineT m (Is a) r)
k = ([MachineT m (Is a) r] -> MachineT m (Is a) r)
-> [(a -> MachineT m (Is a) r, MachineT m (Is a) r)]
-> Step (Is a) r (MachineT m (Is a) r)
forall b r a o. ([b] -> r) -> [(a -> b, b)] -> Step (Is a) o r
continue [MachineT m (Is a) r] -> MachineT m (Is a) r
forall (m :: * -> *) a r.
(Monad m, Semigroup r) =>
[ProcessT m a r] -> ProcessT m a r
fanout [(a -> MachineT m (Is a) r, MachineT m (Is a) r)]
ws
go [(a -> MachineT m (Is a) r, MachineT m (Is a) r)]
-> [(a -> MachineT m (Is a) r, MachineT m (Is a) r)]
waiting [r] -> [r]
acc (MachineT m (Is a) r
m:[MachineT m (Is a) r]
ms) = MachineT m (Is a) r -> m (Step (Is a) r (MachineT m (Is a) r))
forall (m :: * -> *) (k :: * -> *) o.
MachineT m k o -> m (Step k o (MachineT m k o))
runMachineT MachineT m (Is a) r
m m (Step (Is a) r (MachineT m (Is a) r))
-> (Step (Is a) r (MachineT m (Is a) r)
-> m (Step (Is a) r (MachineT m (Is a) r)))
-> m (Step (Is a) r (MachineT m (Is a) r))
forall a b. m a -> (a -> m b) -> m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \Step (Is a) r (MachineT m (Is a) r)
v -> case Step (Is a) r (MachineT m (Is a) r)
v of
Step (Is a) r (MachineT m (Is a) r)
Stop -> ([(a -> MachineT m (Is a) r, MachineT m (Is a) r)]
-> [(a -> MachineT m (Is a) r, MachineT m (Is a) r)])
-> ([r] -> [r])
-> [MachineT m (Is a) r]
-> m (Step (Is a) r (MachineT m (Is a) r))
go [(a -> MachineT m (Is a) r, MachineT m (Is a) r)]
-> [(a -> MachineT m (Is a) r, MachineT m (Is a) r)]
waiting [r] -> [r]
acc [MachineT m (Is a) r]
ms
Yield r
x MachineT m (Is a) r
k -> ([(a -> MachineT m (Is a) r, MachineT m (Is a) r)]
-> [(a -> MachineT m (Is a) r, MachineT m (Is a) r)])
-> ([r] -> [r])
-> [MachineT m (Is a) r]
-> m (Step (Is a) r (MachineT m (Is a) r))
go [(a -> MachineT m (Is a) r, MachineT m (Is a) r)]
-> [(a -> MachineT m (Is a) r, MachineT m (Is a) r)]
waiting ([r] -> [r]
acc ([r] -> [r]) -> ([r] -> [r]) -> [r] -> [r]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (r
xr -> [r] -> [r]
forall a. a -> [a] -> [a]
:)) (MachineT m (Is a) r
kMachineT m (Is a) r
-> [MachineT m (Is a) r] -> [MachineT m (Is a) r]
forall a. a -> [a] -> [a]
:[MachineT m (Is a) r]
ms)
Await t -> MachineT m (Is a) r
f Is a t
Refl MachineT m (Is a) r
k -> ([(a -> MachineT m (Is a) r, MachineT m (Is a) r)]
-> [(a -> MachineT m (Is a) r, MachineT m (Is a) r)])
-> ([r] -> [r])
-> [MachineT m (Is a) r]
-> m (Step (Is a) r (MachineT m (Is a) r))
go ([(a -> MachineT m (Is a) r, MachineT m (Is a) r)]
-> [(a -> MachineT m (Is a) r, MachineT m (Is a) r)]
waiting ([(a -> MachineT m (Is a) r, MachineT m (Is a) r)]
-> [(a -> MachineT m (Is a) r, MachineT m (Is a) r)])
-> ([(a -> MachineT m (Is a) r, MachineT m (Is a) r)]
-> [(a -> MachineT m (Is a) r, MachineT m (Is a) r)])
-> [(a -> MachineT m (Is a) r, MachineT m (Is a) r)]
-> [(a -> MachineT m (Is a) r, MachineT m (Is a) r)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((a -> MachineT m (Is a) r
t -> MachineT m (Is a) r
f, MachineT m (Is a) r
k)(a -> MachineT m (Is a) r, MachineT m (Is a) r)
-> [(a -> MachineT m (Is a) r, MachineT m (Is a) r)]
-> [(a -> MachineT m (Is a) r, MachineT m (Is a) r)]
forall a. a -> [a] -> [a]
:)) [r] -> [r]
acc [MachineT m (Is a) r]
ms
fanoutSteps :: forall m a r. (Monad m, Monoid r)
=> [ProcessT m a r] -> ProcessT m a r
fanoutSteps :: forall (m :: * -> *) a r.
(Monad m, Monoid r) =>
[ProcessT m a r] -> ProcessT m a r
fanoutSteps = m (Step (Is a) r (MachineT m (Is a) r)) -> MachineT m (Is a) r
forall (m :: * -> *) (k :: * -> *) o.
m (Step k o (MachineT m k o)) -> MachineT m k o
MachineT (m (Step (Is a) r (MachineT m (Is a) r)) -> MachineT m (Is a) r)
-> ([MachineT m (Is a) r]
-> m (Step (Is a) r (MachineT m (Is a) r)))
-> [MachineT m (Is a) r]
-> MachineT m (Is a) r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([(a -> MachineT m (Is a) r, MachineT m (Is a) r)]
-> [(a -> MachineT m (Is a) r, MachineT m (Is a) r)])
-> ([r] -> [r])
-> [MachineT m (Is a) r]
-> m (Step (Is a) r (MachineT m (Is a) r))
go [(a -> MachineT m (Is a) r, MachineT m (Is a) r)]
-> [(a -> MachineT m (Is a) r, MachineT m (Is a) r)]
forall a. a -> a
id [r] -> [r]
forall a. a -> a
id
where
go :: ([(a -> ProcessT m a r, ProcessT m a r)]
-> [(a -> ProcessT m a r, ProcessT m a r)])
-> ([r] -> [r])
-> [ProcessT m a r]
-> m (Step (Is a) r (ProcessT m a r))
go :: ([(a -> MachineT m (Is a) r, MachineT m (Is a) r)]
-> [(a -> MachineT m (Is a) r, MachineT m (Is a) r)])
-> ([r] -> [r])
-> [MachineT m (Is a) r]
-> m (Step (Is a) r (MachineT m (Is a) r))
go [(a -> MachineT m (Is a) r, MachineT m (Is a) r)]
-> [(a -> MachineT m (Is a) r, MachineT m (Is a) r)]
waiting [r] -> [r]
acc [] = case ([(a -> MachineT m (Is a) r, MachineT m (Is a) r)]
-> [(a -> MachineT m (Is a) r, MachineT m (Is a) r)]
waiting [], [r] -> r
forall a. Monoid a => [a] -> a
mconcat ([r] -> [r]
acc [])) of
([(a -> MachineT m (Is a) r, MachineT m (Is a) r)]
ws, r
xs) -> Step (Is a) r (MachineT m (Is a) r)
-> m (Step (Is a) r (MachineT m (Is a) r))
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Step (Is a) r (MachineT m (Is a) r)
-> m (Step (Is a) r (MachineT m (Is a) r)))
-> (MachineT m (Is a) r -> Step (Is a) r (MachineT m (Is a) r))
-> MachineT m (Is a) r
-> m (Step (Is a) r (MachineT m (Is a) r))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. r -> MachineT m (Is a) r -> Step (Is a) r (MachineT m (Is a) r)
forall (k :: * -> *) o r. o -> r -> Step k o r
Yield r
xs (MachineT m (Is a) r -> m (Step (Is a) r (MachineT m (Is a) r)))
-> MachineT m (Is a) r -> m (Step (Is a) r (MachineT m (Is a) r))
forall a b. (a -> b) -> a -> b
$ Step (Is a) r (MachineT m (Is a) r) -> MachineT m (Is a) r
forall (m :: * -> *) (k :: * -> *) o.
Monad m =>
Step k o (MachineT m k o) -> MachineT m k o
encased (([MachineT m (Is a) r] -> MachineT m (Is a) r)
-> [(a -> MachineT m (Is a) r, MachineT m (Is a) r)]
-> Step (Is a) r (MachineT m (Is a) r)
forall b r a o. ([b] -> r) -> [(a -> b, b)] -> Step (Is a) o r
continue [MachineT m (Is a) r] -> MachineT m (Is a) r
forall (m :: * -> *) a r.
(Monad m, Monoid r) =>
[ProcessT m a r] -> ProcessT m a r
fanoutSteps [(a -> MachineT m (Is a) r, MachineT m (Is a) r)]
ws)
go [(a -> MachineT m (Is a) r, MachineT m (Is a) r)]
-> [(a -> MachineT m (Is a) r, MachineT m (Is a) r)]
waiting [r] -> [r]
acc (MachineT m (Is a) r
m:[MachineT m (Is a) r]
ms) = MachineT m (Is a) r -> m (Step (Is a) r (MachineT m (Is a) r))
forall (m :: * -> *) (k :: * -> *) o.
MachineT m k o -> m (Step k o (MachineT m k o))
runMachineT MachineT m (Is a) r
m m (Step (Is a) r (MachineT m (Is a) r))
-> (Step (Is a) r (MachineT m (Is a) r)
-> m (Step (Is a) r (MachineT m (Is a) r)))
-> m (Step (Is a) r (MachineT m (Is a) r))
forall a b. m a -> (a -> m b) -> m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \Step (Is a) r (MachineT m (Is a) r)
v -> case Step (Is a) r (MachineT m (Is a) r)
v of
Step (Is a) r (MachineT m (Is a) r)
Stop -> ([(a -> MachineT m (Is a) r, MachineT m (Is a) r)]
-> [(a -> MachineT m (Is a) r, MachineT m (Is a) r)])
-> ([r] -> [r])
-> [MachineT m (Is a) r]
-> m (Step (Is a) r (MachineT m (Is a) r))
go [(a -> MachineT m (Is a) r, MachineT m (Is a) r)]
-> [(a -> MachineT m (Is a) r, MachineT m (Is a) r)]
waiting [r] -> [r]
acc [MachineT m (Is a) r]
ms
Yield r
x MachineT m (Is a) r
k -> ([(a -> MachineT m (Is a) r, MachineT m (Is a) r)]
-> [(a -> MachineT m (Is a) r, MachineT m (Is a) r)])
-> ([r] -> [r])
-> [MachineT m (Is a) r]
-> m (Step (Is a) r (MachineT m (Is a) r))
go [(a -> MachineT m (Is a) r, MachineT m (Is a) r)]
-> [(a -> MachineT m (Is a) r, MachineT m (Is a) r)]
waiting ([r] -> [r]
acc ([r] -> [r]) -> ([r] -> [r]) -> [r] -> [r]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (r
xr -> [r] -> [r]
forall a. a -> [a] -> [a]
:)) (MachineT m (Is a) r
kMachineT m (Is a) r
-> [MachineT m (Is a) r] -> [MachineT m (Is a) r]
forall a. a -> [a] -> [a]
:[MachineT m (Is a) r]
ms)
Await t -> MachineT m (Is a) r
f Is a t
Refl MachineT m (Is a) r
k -> ([(a -> MachineT m (Is a) r, MachineT m (Is a) r)]
-> [(a -> MachineT m (Is a) r, MachineT m (Is a) r)])
-> ([r] -> [r])
-> [MachineT m (Is a) r]
-> m (Step (Is a) r (MachineT m (Is a) r))
go ([(a -> MachineT m (Is a) r, MachineT m (Is a) r)]
-> [(a -> MachineT m (Is a) r, MachineT m (Is a) r)]
waiting ([(a -> MachineT m (Is a) r, MachineT m (Is a) r)]
-> [(a -> MachineT m (Is a) r, MachineT m (Is a) r)])
-> ([(a -> MachineT m (Is a) r, MachineT m (Is a) r)]
-> [(a -> MachineT m (Is a) r, MachineT m (Is a) r)])
-> [(a -> MachineT m (Is a) r, MachineT m (Is a) r)]
-> [(a -> MachineT m (Is a) r, MachineT m (Is a) r)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((a -> MachineT m (Is a) r
t -> MachineT m (Is a) r
f, MachineT m (Is a) r
k)(a -> MachineT m (Is a) r, MachineT m (Is a) r)
-> [(a -> MachineT m (Is a) r, MachineT m (Is a) r)]
-> [(a -> MachineT m (Is a) r, MachineT m (Is a) r)]
forall a. a -> [a] -> [a]
:)) [r] -> [r]
acc [MachineT m (Is a) r]
ms