{-# LANGUAGE CPP, FlexibleContexts, GADTs, ScopedTypeVariables #-}
-- | Provide a notion of fanout wherein a single input is passed to
-- several consumers. The consumers are run concurrently.
module Data.Machine.Concurrent.Fanout (fanout, fanoutSteps) where
import Control.Arrow (first, second)
import Control.Concurrent.Async.Lifted (Async, async, wait)
import Control.Monad (foldM)
import Control.Monad.Trans.Control (MonadBaseControl, StM)
import Data.Machine (Step(..), MachineT(..), encased, stopped, ProcessT, Is(..))
import Data.Machine.Concurrent.AsyncStep (MachineStep)
import Data.Maybe (catMaybes)
#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ < 710
import Data.Monoid (Monoid, mempty, mconcat)
#endif
import Data.Semigroup (Semigroup(sconcat))
import Data.List.NonEmpty (NonEmpty((:|)))
#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ < 710
import Data.Coerce (coerce)
#endif

-- | Feed a value to a 'ProcessT' at an 'Await' 'Step'. If the
-- 'ProcessT' is awaiting a value, then its next step is
-- returned. Otherwise, the original process is returned.
feed :: forall m a b. MonadBaseControl IO m
     => a -> ProcessT m a b
     -> m (Async (StM m (MachineStep m (Is a) b)))
feed :: a -> ProcessT m a b -> m (Async (StM m (MachineStep m (Is a) b)))
feed a
x ProcessT m a b
m = m (MachineStep m (Is a) b)
-> m (Async (StM m (MachineStep m (Is a) b)))
forall (m :: * -> *) a.
MonadBaseControl IO m =>
m a -> m (Async (StM m a))
async (m (MachineStep m (Is a) b)
 -> m (Async (StM m (MachineStep m (Is a) b))))
-> m (MachineStep m (Is a) b)
-> m (Async (StM m (MachineStep m (Is a) b)))
forall a b. (a -> b) -> a -> b
$ ProcessT m a b -> m (MachineStep m (Is a) b)
forall (m :: * -> *) (k :: * -> *) o.
MachineT m k o -> m (Step k o (MachineT m k o))
runMachineT ProcessT m a b
m m (MachineStep m (Is a) b)
-> (MachineStep m (Is a) b -> m (MachineStep m (Is a) b))
-> m (MachineStep m (Is a) b)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \(MachineStep m (Is a) b
v :: MachineStep m (Is a) b) ->
             case MachineStep m (Is a) b
v of
               Await t -> ProcessT m a b
f Is a t
Refl ProcessT m a b
_ -> ProcessT m a b -> m (MachineStep m (Is a) b)
forall (m :: * -> *) (k :: * -> *) o.
MachineT m k o -> m (Step k o (MachineT m k o))
runMachineT (t -> ProcessT m a b
f a
t
x)
               MachineStep m (Is a) b
s -> MachineStep m (Is a) b -> m (MachineStep m (Is a) b)
forall (m :: * -> *) a. Monad m => a -> m a
return MachineStep m (Is a) b
s

-- | Like 'Data.List.mapAccumL' but with a monadic accumulating
-- function.
mapAccumLM :: MonadBaseControl IO m
           => (acc -> x -> m (acc, y)) -> acc -> [Async (StM m x)]
           -> m (acc, [y])
mapAccumLM :: (acc -> x -> m (acc, y))
-> acc -> [Async (StM m x)] -> m (acc, [y])
mapAccumLM acc -> x -> m (acc, y)
f acc
z = ((acc, [y] -> [y]) -> (acc, [y]))
-> m (acc, [y] -> [y]) -> m (acc, [y])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((([y] -> [y]) -> [y]) -> (acc, [y] -> [y]) -> (acc, [y])
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (d, b) (d, c)
second (([y] -> [y]) -> [y] -> [y]
forall a b. (a -> b) -> a -> b
$ [])) (m (acc, [y] -> [y]) -> m (acc, [y]))
-> ([Async (StM m x)] -> m (acc, [y] -> [y]))
-> [Async (StM m x)]
-> m (acc, [y])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((acc, [y] -> [y]) -> Async (StM m x) -> m (acc, [y] -> [y]))
-> (acc, [y] -> [y]) -> [Async (StM m x)] -> m (acc, [y] -> [y])
forall (t :: * -> *) (m :: * -> *) b a.
(Foldable t, Monad m) =>
(b -> a -> m b) -> b -> t a -> m b
foldM (acc, [y] -> [y]) -> Async (StM m x) -> m (acc, [y] -> [y])
aux (acc
z,[y] -> [y]
forall a. a -> a
id)
  where aux :: (acc, [y] -> [y]) -> Async (StM m x) -> m (acc, [y] -> [y])
aux (acc
acc,[y] -> [y]
ys) Async (StM m x)
x = do (acc
yielded, y
nxt) <- Async (StM m x) -> m x
forall (m :: * -> *) a.
MonadBaseControl IO m =>
Async (StM m a) -> m a
wait Async (StM m x)
x m x -> (x -> m (acc, y)) -> m (acc, y)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= acc -> x -> m (acc, y)
f acc
acc
                            (acc, [y] -> [y]) -> m (acc, [y] -> [y])
forall (m :: * -> *) a. Monad m => a -> m a
return ((acc, [y] -> [y]) -> m (acc, [y] -> [y]))
-> (acc, [y] -> [y]) -> m (acc, [y] -> [y])
forall a b. (a -> b) -> a -> b
$ (acc
yielded, (y
nxty -> [y] -> [y]
forall a. a -> [a] -> [a]
:) ([y] -> [y]) -> ([y] -> [y]) -> [y] -> [y]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [y] -> [y]
ys)

-- | Exhaust a sequence of all successive 'Yield' steps taken by a
-- 'MachineT'. Returns the list of yielded values and the next
-- (non-Yield) step of the machine.
flushYields :: Monad m
            => Step k o (MachineT m k o) -> m ([o], Maybe (MachineT m k o))
flushYields :: Step k o (MachineT m k o) -> m ([o], Maybe (MachineT m k o))
flushYields = ([o] -> [o])
-> Step k o (MachineT m k o) -> m ([o], Maybe (MachineT m k o))
forall (m :: * -> *) a o (k :: * -> *).
Monad m =>
([a] -> [o])
-> Step k o (MachineT m k o) -> m ([o], Maybe (MachineT m k o))
go [o] -> [o]
forall a. a -> a
id
  where go :: ([a] -> [o])
-> Step k o (MachineT m k o) -> m ([o], Maybe (MachineT m k o))
go [a] -> [o]
rs (Yield o
o MachineT m k o
s) = MachineT m k o -> m (Step k o (MachineT m k o))
forall (m :: * -> *) (k :: * -> *) o.
MachineT m k o -> m (Step k o (MachineT m k o))
runMachineT MachineT m k o
s m (Step k o (MachineT m k o))
-> (Step k o (MachineT m k o) -> m ([o], Maybe (MachineT m k o)))
-> m ([o], Maybe (MachineT m k o))
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= ([a] -> [o])
-> Step k o (MachineT m k o) -> m ([o], Maybe (MachineT m k o))
go ((o
oo -> [o] -> [o]
forall a. a -> [a] -> [a]
:) ([o] -> [o]) -> ([a] -> [o]) -> [a] -> [o]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [a] -> [o]
rs)
        go [a] -> [o]
rs Step k o (MachineT m k o)
Stop = ([o], Maybe (MachineT m k o)) -> m ([o], Maybe (MachineT m k o))
forall (m :: * -> *) a. Monad m => a -> m a
return ([a] -> [o]
rs [], Maybe (MachineT m k o)
forall a. Maybe a
Nothing)
        go [a] -> [o]
rs Step k o (MachineT m k o)
s = ([o], Maybe (MachineT m k o)) -> m ([o], Maybe (MachineT m k o))
forall (m :: * -> *) a. Monad m => a -> m a
return ([a] -> [o]
rs [], MachineT m k o -> Maybe (MachineT m k o)
forall a. a -> Maybe a
Just (MachineT m k o -> Maybe (MachineT m k o))
-> MachineT m k o -> Maybe (MachineT m k o)
forall a b. (a -> b) -> a -> b
$ Step k o (MachineT m k o) -> MachineT m k o
forall (m :: * -> *) (k :: * -> *) o.
Monad m =>
Step k o (MachineT m k o) -> MachineT m k o
encased Step k o (MachineT m k o)
s)

-- | Share inputs with each of a list of processes in lockstep. Any
-- values yielded by the processes for a given input are combined into
-- a single yield from the composite process.
fanout :: (MonadBaseControl IO m, Semigroup r)
       => [ProcessT m a r] -> ProcessT m a r
fanout :: [ProcessT m a r] -> ProcessT m a r
fanout [] = ProcessT m a r
forall (k :: * -> *) b. Machine k b
stopped
fanout [ProcessT m a r]
xs = Step (Is a) r (ProcessT m a r) -> ProcessT m a r
forall (m :: * -> *) (k :: * -> *) o.
Monad m =>
Step k o (MachineT m k o) -> MachineT m k o
encased (Step (Is a) r (ProcessT m a r) -> ProcessT m a r)
-> Step (Is a) r (ProcessT m a r) -> ProcessT m a r
forall a b. (a -> b) -> a -> b
$ (a -> ProcessT m a r)
-> Is a a -> ProcessT m a r -> Step (Is a) r (ProcessT m a r)
forall (k :: * -> *) o r t. (t -> r) -> k t -> r -> Step k o r
Await (m (Step (Is a) r (ProcessT m a r)) -> ProcessT m a r
forall (m :: * -> *) (k :: * -> *) o.
m (Step k o (MachineT m k o)) -> MachineT m k o
MachineT (m (Step (Is a) r (ProcessT m a r)) -> ProcessT m a r)
-> (a -> m (Step (Is a) r (ProcessT m a r))) -> a -> ProcessT m a r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> m (Step (Is a) r (ProcessT m a r))
aux) Is a a
forall a. Is a a
Refl ([ProcessT m a r] -> ProcessT m a r
forall (m :: * -> *) r a.
(MonadBaseControl IO m, Semigroup r) =>
[ProcessT m a r] -> ProcessT m a r
fanout [ProcessT m a r]
xs)
  where aux :: a -> m (Step (Is a) r (ProcessT m a r))
aux a
y = do ([r]
rs,[Maybe (ProcessT m a r)]
xs') <- (ProcessT m a r
 -> m (Async (StM m (Step (Is a) r (ProcessT m a r)))))
-> [ProcessT m a r]
-> m [Async (StM m (Step (Is a) r (ProcessT m a r)))]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (a
-> ProcessT m a r
-> m (Async (StM m (Step (Is a) r (ProcessT m a r))))
forall (m :: * -> *) a b.
MonadBaseControl IO m =>
a -> ProcessT m a b -> m (Async (StM m (MachineStep m (Is a) b)))
feed a
y) [ProcessT m a r]
xs m [Async (StM m (Step (Is a) r (ProcessT m a r)))]
-> ([Async (StM m (Step (Is a) r (ProcessT m a r)))]
    -> m ([r], [Maybe (ProcessT m a r)]))
-> m ([r], [Maybe (ProcessT m a r)])
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= ([r]
 -> Step (Is a) r (ProcessT m a r)
 -> m ([r], Maybe (ProcessT m a r)))
-> [r]
-> [Async (StM m (Step (Is a) r (ProcessT m a r)))]
-> m ([r], [Maybe (ProcessT m a r)])
forall (m :: * -> *) acc x y.
MonadBaseControl IO m =>
(acc -> x -> m (acc, y))
-> acc -> [Async (StM m x)] -> m (acc, [y])
mapAccumLM [r]
-> Step (Is a) r (ProcessT m a r)
-> m ([r], Maybe (ProcessT m a r))
forall (m :: * -> *) o (k :: * -> *).
Monad m =>
[o] -> Step k o (MachineT m k o) -> m ([o], Maybe (MachineT m k o))
yields []
                   let nxt :: ProcessT m a r
nxt = [ProcessT m a r] -> ProcessT m a r
forall (m :: * -> *) r a.
(MonadBaseControl IO m, Semigroup r) =>
[ProcessT m a r] -> ProcessT m a r
fanout ([ProcessT m a r] -> ProcessT m a r)
-> [ProcessT m a r] -> ProcessT m a r
forall a b. (a -> b) -> a -> b
$ [Maybe (ProcessT m a r)] -> [ProcessT m a r]
forall a. [Maybe a] -> [a]
catMaybes [Maybe (ProcessT m a r)]
xs'
                   case [r]
rs of
                     [] -> ProcessT m a r -> m (Step (Is a) r (ProcessT m a r))
forall (m :: * -> *) (k :: * -> *) o.
MachineT m k o -> m (Step k o (MachineT m k o))
runMachineT ProcessT m a r
nxt
                     (r
r:[r]
rs') -> Step (Is a) r (ProcessT m a r)
-> m (Step (Is a) r (ProcessT m a r))
forall (m :: * -> *) a. Monad m => a -> m a
return (Step (Is a) r (ProcessT m a r)
 -> m (Step (Is a) r (ProcessT m a r)))
-> Step (Is a) r (ProcessT m a r)
-> m (Step (Is a) r (ProcessT m a r))
forall a b. (a -> b) -> a -> b
$ r -> ProcessT m a r -> Step (Is a) r (ProcessT m a r)
forall (k :: * -> *) o r. o -> r -> Step k o r
Yield (NonEmpty r -> r
forall a. Semigroup a => NonEmpty a -> a
sconcat (NonEmpty r -> r) -> NonEmpty r -> r
forall a b. (a -> b) -> a -> b
$ r
r r -> [r] -> NonEmpty r
forall a. a -> [a] -> NonEmpty a
:| [r]
rs') ProcessT m a r
nxt
        yields :: [o] -> Step k o (MachineT m k o) -> m ([o], Maybe (MachineT m k o))
yields [o]
rs Step k o (MachineT m k o)
Stop = ([o], Maybe (MachineT m k o)) -> m ([o], Maybe (MachineT m k o))
forall (m :: * -> *) a. Monad m => a -> m a
return ([o]
rs,Maybe (MachineT m k o)
forall a. Maybe a
Nothing)
        yields [o]
rs y :: Step k o (MachineT m k o)
y@Yield{} = ([o] -> [o])
-> ([o], Maybe (MachineT m k o)) -> ([o], Maybe (MachineT m k o))
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (b, d) (c, d)
first ([o] -> [o] -> [o]
forall a. [a] -> [a] -> [a]
++ [o]
rs) (([o], Maybe (MachineT m k o)) -> ([o], Maybe (MachineT m k o)))
-> m ([o], Maybe (MachineT m k o))
-> m ([o], Maybe (MachineT m k o))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Step k o (MachineT m k o) -> m ([o], Maybe (MachineT m k o))
forall (m :: * -> *) (k :: * -> *) o.
Monad m =>
Step k o (MachineT m k o) -> m ([o], Maybe (MachineT m k o))
flushYields Step k o (MachineT m k o)
y
        yields [o]
rs a :: Step k o (MachineT m k o)
a@Await{} = ([o], Maybe (MachineT m k o)) -> m ([o], Maybe (MachineT m k o))
forall (m :: * -> *) a. Monad m => a -> m a
return ([o]
rs, MachineT m k o -> Maybe (MachineT m k o)
forall a. a -> Maybe a
Just (MachineT m k o -> Maybe (MachineT m k o))
-> MachineT m k o -> Maybe (MachineT m k o)
forall a b. (a -> b) -> a -> b
$ Step k o (MachineT m k o) -> MachineT m k o
forall (m :: * -> *) (k :: * -> *) o.
Monad m =>
Step k o (MachineT m k o) -> MachineT m k o
encased Step k o (MachineT m k o)
a)

-- | Share inputs with each of a list of processes in lockstep. If
-- none of the processes yields a value, the composite process will
-- itself yield 'mempty'. The idea is to provide a handle on steps
-- only executed for their side effects. For instance, if you want to
-- run a collection of 'ProcessT's that await but don't yield some
-- number of times, you can use 'fanOutSteps . map (fmap (const ()))'
-- followed by a 'taking' process.
fanoutSteps :: (MonadBaseControl IO m, Monoid r)
            => [ProcessT m a r] -> ProcessT m a r
fanoutSteps :: [ProcessT m a r] -> ProcessT m a r
fanoutSteps [] = ProcessT m a r
forall (k :: * -> *) b. Machine k b
stopped
fanoutSteps [ProcessT m a r]
xs = Step (Is a) r (ProcessT m a r) -> ProcessT m a r
forall (m :: * -> *) (k :: * -> *) o.
Monad m =>
Step k o (MachineT m k o) -> MachineT m k o
encased (Step (Is a) r (ProcessT m a r) -> ProcessT m a r)
-> Step (Is a) r (ProcessT m a r) -> ProcessT m a r
forall a b. (a -> b) -> a -> b
$ (a -> ProcessT m a r)
-> Is a a -> ProcessT m a r -> Step (Is a) r (ProcessT m a r)
forall (k :: * -> *) o r t. (t -> r) -> k t -> r -> Step k o r
Await (m (Step (Is a) r (ProcessT m a r)) -> ProcessT m a r
forall (m :: * -> *) (k :: * -> *) o.
m (Step k o (MachineT m k o)) -> MachineT m k o
MachineT (m (Step (Is a) r (ProcessT m a r)) -> ProcessT m a r)
-> (a -> m (Step (Is a) r (ProcessT m a r))) -> a -> ProcessT m a r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> m (Step (Is a) r (ProcessT m a r))
aux) Is a a
forall a. Is a a
Refl ([ProcessT m a r] -> ProcessT m a r
forall (m :: * -> *) r a.
(MonadBaseControl IO m, Monoid r) =>
[ProcessT m a r] -> ProcessT m a r
fanoutSteps [ProcessT m a r]
xs)
  where aux :: a -> m (Step (Is a) r (ProcessT m a r))
aux a
y = do ([r]
rs,[Maybe (ProcessT m a r)]
xs') <- (ProcessT m a r
 -> m (Async (StM m (Step (Is a) r (ProcessT m a r)))))
-> [ProcessT m a r]
-> m [Async (StM m (Step (Is a) r (ProcessT m a r)))]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (a
-> ProcessT m a r
-> m (Async (StM m (Step (Is a) r (ProcessT m a r))))
forall (m :: * -> *) a b.
MonadBaseControl IO m =>
a -> ProcessT m a b -> m (Async (StM m (MachineStep m (Is a) b)))
feed a
y) [ProcessT m a r]
xs m [Async (StM m (Step (Is a) r (ProcessT m a r)))]
-> ([Async (StM m (Step (Is a) r (ProcessT m a r)))]
    -> m ([r], [Maybe (ProcessT m a r)]))
-> m ([r], [Maybe (ProcessT m a r)])
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= ([r]
 -> Step (Is a) r (ProcessT m a r)
 -> m ([r], Maybe (ProcessT m a r)))
-> [r]
-> [Async (StM m (Step (Is a) r (ProcessT m a r)))]
-> m ([r], [Maybe (ProcessT m a r)])
forall (m :: * -> *) acc x y.
MonadBaseControl IO m =>
(acc -> x -> m (acc, y))
-> acc -> [Async (StM m x)] -> m (acc, [y])
mapAccumLM [r]
-> Step (Is a) r (ProcessT m a r)
-> m ([r], Maybe (ProcessT m a r))
forall (m :: * -> *) o (k :: * -> *).
Monad m =>
[o] -> Step k o (MachineT m k o) -> m ([o], Maybe (MachineT m k o))
yields []
                   let nxt :: ProcessT m a r
nxt = [ProcessT m a r] -> ProcessT m a r
forall (m :: * -> *) r a.
(MonadBaseControl IO m, Monoid r) =>
[ProcessT m a r] -> ProcessT m a r
fanoutSteps ([ProcessT m a r] -> ProcessT m a r)
-> [ProcessT m a r] -> ProcessT m a r
forall a b. (a -> b) -> a -> b
$ [Maybe (ProcessT m a r)] -> [ProcessT m a r]
forall a. [Maybe a] -> [a]
catMaybes [Maybe (ProcessT m a r)]
xs'
                   if [r] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [r]
rs
                   then Step (Is a) r (ProcessT m a r)
-> m (Step (Is a) r (ProcessT m a r))
forall (m :: * -> *) a. Monad m => a -> m a
return (Step (Is a) r (ProcessT m a r)
 -> m (Step (Is a) r (ProcessT m a r)))
-> Step (Is a) r (ProcessT m a r)
-> m (Step (Is a) r (ProcessT m a r))
forall a b. (a -> b) -> a -> b
$ r -> ProcessT m a r -> Step (Is a) r (ProcessT m a r)
forall (k :: * -> *) o r. o -> r -> Step k o r
Yield r
forall a. Monoid a => a
mempty ProcessT m a r
nxt
                   else Step (Is a) r (ProcessT m a r)
-> m (Step (Is a) r (ProcessT m a r))
forall (m :: * -> *) a. Monad m => a -> m a
return (Step (Is a) r (ProcessT m a r)
 -> m (Step (Is a) r (ProcessT m a r)))
-> Step (Is a) r (ProcessT m a r)
-> m (Step (Is a) r (ProcessT m a r))
forall a b. (a -> b) -> a -> b
$ r -> ProcessT m a r -> Step (Is a) r (ProcessT m a r)
forall (k :: * -> *) o r. o -> r -> Step k o r
Yield ([r] -> r
forall a. Monoid a => [a] -> a
mconcat [r]
rs) ProcessT m a r
nxt
        yields :: [o] -> Step k o (MachineT m k o) -> m ([o], Maybe (MachineT m k o))
yields [o]
rs Step k o (MachineT m k o)
Stop = ([o], Maybe (MachineT m k o)) -> m ([o], Maybe (MachineT m k o))
forall (m :: * -> *) a. Monad m => a -> m a
return ([o]
rs,Maybe (MachineT m k o)
forall a. Maybe a
Nothing)
        yields [o]
rs y :: Step k o (MachineT m k o)
y@Yield{} = ([o] -> [o])
-> ([o], Maybe (MachineT m k o)) -> ([o], Maybe (MachineT m k o))
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (b, d) (c, d)
first ([o] -> [o] -> [o]
forall a. [a] -> [a] -> [a]
++[o]
rs) (([o], Maybe (MachineT m k o)) -> ([o], Maybe (MachineT m k o)))
-> m ([o], Maybe (MachineT m k o))
-> m ([o], Maybe (MachineT m k o))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Step k o (MachineT m k o) -> m ([o], Maybe (MachineT m k o))
forall (m :: * -> *) (k :: * -> *) o.
Monad m =>
Step k o (MachineT m k o) -> m ([o], Maybe (MachineT m k o))
flushYields Step k o (MachineT m k o)
y
        yields [o]
rs a :: Step k o (MachineT m k o)
a@Await{} = ([o], Maybe (MachineT m k o)) -> m ([o], Maybe (MachineT m k o))
forall (m :: * -> *) a. Monad m => a -> m a
return ([o]
rs, MachineT m k o -> Maybe (MachineT m k o)
forall a. a -> Maybe a
Just (MachineT m k o -> Maybe (MachineT m k o))
-> MachineT m k o -> Maybe (MachineT m k o)
forall a b. (a -> b) -> a -> b
$ Step k o (MachineT m k o) -> MachineT m k o
forall (m :: * -> *) (k :: * -> *) o.
Monad m =>
Step k o (MachineT m k o) -> MachineT m k o
encased Step k o (MachineT m k o)
a)