netwire-4.0.0: Control/Wire/Prefab/Effect.hs
-- |
-- Module: Control.Wire.Prefab.Effect
-- Copyright: (c) 2012 Ertugrul Soeylemez
-- License: BSD3
-- Maintainer: Ertugrul Soeylemez <es@ertes.de>
--
-- Effectful wires.
module Control.Wire.Prefab.Effect
( -- * Monadic effects
-- ** Simple
perform,
-- ** Exception-aware
execute,
execute_,
executeWith,
executeWith_,
-- * Branching
branch,
quit,
quitWith
)
where
import qualified Data.Bifunctor as Bi
import Control.Exception.Lifted
import Control.Monad
import Control.Monad.Trans.Control
import Control.Wire.Types
import Control.Wire.Wire
import Data.List
import Data.Monoid
-- | Branch according to the unterlying 'MonadPlus' instance. Note that
-- this wire branches at every instant.
--
-- * Depends: current instant.
branch :: (MonadPlus m) => Wire e m [a] a
branch = mkFixM $ \_ -> liftM Right . foldl' mplus mzero . map return
-- | Variant of 'executeWith' for the 'LastException' inhibition monoid.
--
-- * Depends: current instant.
--
-- * Inhibits: when the action throws an exception.
execute ::
(MonadBaseControl IO m)
=> Wire LastException m (m a) a
execute = executeWith (Last . Just)
-- | Variant of 'executeWith_' for the 'LastException' inhibition monoid.
--
-- * Depends: current instant, if the given function is strict.
--
-- * Inhibits: when the action throws an exception.
execute_ ::
(MonadBaseControl IO m)
=> (a -> m b)
-> Wire LastException m a b
execute_ = executeWith_ (Last . Just)
-- | Perform the input monadic action at every instant.
--
-- * Depends: current instant.
--
-- * Inhibits: when the action throws an exception.
executeWith ::
(MonadBaseControl IO m)
=> (SomeException -> e) -- ^ Turns an exception into an inhibition value.
-> Wire e m (m a) a
executeWith fromEx = mkFixM $ \_ c -> liftM (Bi.first fromEx) (try c)
-- | Perform the given monadic action at every instant.
--
-- * Depends: current instant, if the given function is strict.
--
-- * Inhibits: when the action throws an exception.
executeWith_ ::
(MonadBaseControl IO m)
=> (SomeException -> e) -- ^ Turns an exception into an inhibition value.
-> (a -> m b) -- ^ Action to perform.
-> Wire e m a b
executeWith_ fromEx c = mkFixM $ \_ -> liftM (Bi.first fromEx) . try . c
-- | Perform the input monadic action in a wire.
--
-- * Depends: current instant.
perform :: (Monad m) => Wire e m (m b) b
perform = mkFixM . const $ liftM Right
-- | Quits the current branch using 'mzero'.
quit :: (MonadPlus m) => Wire e m a b
quit = mkFixM $ \_ _ -> mzero
-- | Acts like identity in the first instant, then quits the current
-- branch using 'mzero'.
--
-- * Depends: first instant.
quitWith :: (MonadPlus m) => Wire e m a a
quitWith = mkPure $ \_ x -> (Right x, quit)