-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Fold multiple events that happen in a given period of time.
--   
--   Fold multiple events that happen in a given period of time. See
--   <a>Control.FoldDebounce</a>.
@package fold-debounce
@version 0.2.0.11


-- | <pre>
--   module Main (main) where
--   
--   import System.IO (putStrLn)
--   import Control.Concurrent (threadDelay)
--   
--   import qualified Control.FoldDebounce as Fdeb
--   
--   printValue :: Int -&gt; IO ()
--   printValue v = putStrLn ("value = " ++ show v)
--   
--   main :: IO ()
--   main = do
--     trigger &lt;- Fdeb.new Fdeb.Args { Fdeb.cb = printValue, Fdeb.fold = (+), Fdeb.init = 0 }
--                         Fdeb.def { Fdeb.delay = 500000 }
--     let send' = Fdeb.send trigger
--     send' 1
--     send' 2
--     send' 3
--     threadDelay 1000000 -- During this period, "value = 6" is printed.
--     send' 4
--     threadDelay 1000    -- Nothing is printed.
--     send' 5
--     threadDelay 1000000 -- During this period, "value = 9" is printed.
--     Fdeb.close trigger
--   </pre>
--   
--   This module is similar to <a>Control.Debounce</a>. It debouces input
--   events and regulates the frequency at which the action (callback) is
--   executed.
--   
--   The difference from <a>Control.Debounce</a> is:
--   
--   <ul>
--   <li>With <a>Control.Debounce</a>, you cannot pass values to the
--   callback action. This module folds (accumulates) the input events
--   (type <tt>i</tt>) and passes the folded output event (type <tt>o</tt>)
--   to the callback.</li>
--   <li><a>Control.Debounce</a> immediately runs the callback at the first
--   input event. This module just starts a timer at the first input, and
--   runs the callback when the timer expires.</li>
--   </ul>
--   
--   The API and documentation is borrowed from a Perl module called
--   AnyEvent::Debounce. See
--   <a>https://metacpan.org/pod/AnyEvent::Debounce</a>
module Control.FoldDebounce

-- | Create a FoldDebounce trigger.
new :: Args i o -> Opts i o -> IO (Trigger i o)

-- | A trigger to send input events to FoldDebounce. You input data of type
--   <tt>i</tt> to the trigger, and it outputs data of type <tt>o</tt>.
data Trigger i o

-- | Mandatory parameters for <a>new</a>.
data Args i o
Args :: (o -> IO ()) -> (o -> i -> o) -> o -> Args i o

-- | The callback to be called when the output event is emitted. Note that
--   this action is run in a different thread than the one calling
--   <a>send</a>.
--   
--   The callback should not throw any exception. In this case, the
--   <a>Trigger</a> is abnormally closed, causing
--   <a>UnexpectedClosedException</a> when <a>close</a>.
[cb] :: Args i o -> o -> IO ()

-- | The binary operation of left-fold. The left-fold is evaluated
--   strictly.
[fold] :: Args i o -> o -> i -> o

-- | The initial value of the left-fold.
[init] :: Args i o -> o

-- | Optional parameters for <a>new</a>. You can get the default by
--   <a>def</a> function.
data Opts i o

-- | The default value for this type.
def :: Default a => a

-- | The time (in microsecond) to wait after receiving an event before
--   sending it, in case more events happen in the interim.
--   
--   Default: 1 second (1000000)
delay :: Opts i o -> Int

-- | Normally, when an event is received and it's the first of a series, a
--   timer is started, and when that timer expires, all events are sent. If
--   you set this parameter to True, then the timer is reset after each
--   event is received.
--   
--   Default: False
alwaysResetTimer :: Opts i o -> Bool

-- | <a>Args</a> for stacks. Input events are accumulated in a stack, i.e.,
--   the last event is at the head of the list.
forStack :: ([i] -> IO ()) -> Args i [i]

-- | <a>Args</a> for monoids. Input events are appended to the tail.
forMonoid :: Monoid i => (i -> IO ()) -> Args i i

-- | <a>Args</a> that discards input events. Although input events are not
--   folded, they still start the timer and activate the callback.
forVoid :: IO () -> Args i ()

-- | Send an input event.
--   
--   If the <a>Trigger</a> is already closed, it throws
--   <a>AlreadyClosedException</a>. If the <a>Trigger</a> has been
--   abnormally closed, it throws <a>UnexpectedClosedException</a>.
send :: Trigger i o -> i -> IO ()

-- | Close and release the <a>Trigger</a>. If there is a pending output
--   event, the event is fired immediately.
--   
--   If the <a>Trigger</a> has been abnormally closed, it throws
--   <a>UnexpectedClosedException</a>.
close :: Trigger i o -> IO ()

-- | Exception type used by FoldDebounce operations
data OpException

-- | You attempted to <a>send</a> after the trigger is already
--   <a>close</a>d.
AlreadyClosedException :: OpException

-- | The <a>SomeException</a> is thrown in the background thread.
UnexpectedClosedException :: SomeException -> OpException
instance GHC.Show.Show Control.FoldDebounce.OpException
instance GHC.Exception.Type.Exception Control.FoldDebounce.OpException
instance Data.Default.Class.Default (Control.FoldDebounce.Opts i o)
