haste-compiler-0.2.99: libraries/fursuit/src/FRP/Fursuit/Async.hs
module FRP.Fursuit.Async where
import Control.Applicative
import FRP.Fursuit.Signal
import FRP.Fursuit.Sink
import FRP.Fursuit.Pipe
-- | Create an asynchronous signal. When the signal is triggered, it should
-- arrange for a value to written into its obtained pipe at some point in
-- the future; when that happens, the signal continues on its path.
--
-- The signal setup action is guaranteed to be called exactly once per
-- received signal; thus the following code will print 1 two times rather
-- than 1 followed by 2:
-- @
-- ref <- newIORef ()
-- (p, s) <- pipe ()
-- sig <- async $ (\p -> modifyIORef ref (+1) >> write p ref) <$ s
-- sink (\r -> readIORef r >>= print) sig
-- sink (\r -> readIORef r >>= print) sig
-- write p ()
-- @
-- Async is primarily intended as a building block for other more high level
-- signals, and should be used with extreme care as it permits arbitrary side
-- effects to happen in the course of propagating a signal.
--
-- It's also worth noting that triggering the signal returned by async does
-- not trigger the setup signal, but will instead use the last value held by
-- the output signal, if any.
async :: Signal (Pipe a -> IO ()) -> IO (Signal a)
async setup = do
(p,s) <- emptyPipe
perform $ setup <*> pure p
return s