-- |
-- Module:     Control.Wire.Trans.Simple
-- Copyright:  (c) 2011 Ertugrul Soeylemez
-- License:    BSD3
-- Maintainer: Ertugrul Soeylemez <es@ertes.de>
--
-- Simple wire transformers.

module Control.Wire.Trans.Simple
    ( -- * Override input
      WOverrideInput(..),
      (>--)
    )
    where

import Control.Arrow
import Control.Wire.Types


-- | Override input.

class Arrow (>~) => WOverrideInput (>~) where
    -- | Apply the given function to the input, until the argument wire
    -- starts producing.
    --
    -- * Depends: Like argument wire.
    --
    -- * Inhibits: Like argument wire.

    (--<) :: Arrow (>~) => Wire e (>~) a b -> (a -> a) -> Wire e (>~) a b

    infixr 5 --<


instance Monad m => WOverrideInput (Kleisli m) where
    WmPure f --< g =
        WmPure $ \x' ->
            let (mx, w) = f (g x') in
            (mx, either (const $ w --< g) (const w) mx)
    WmGen c --< g =
        WmGen $ \x' -> do
            (mx, w) <- c (g x')
            return (mx, either (const $ w --< g) (const w) mx)



-- | Apply the given function to the input, until the argument wire
-- starts producing.
--
-- * Depends: Like argument wire.
--
-- * Inhibits: Like argument wire.

(>--) :: WOverrideInput (>~) => (a -> a) -> Wire e (>~) a b -> Wire e (>~) a b
(>--) = flip (--<)

infixl 5 >--