bearriver-0.14.4: src/FRP/BearRiver/Basic.hs
-- |
-- Module : FRP.BearRiver.Basic
-- Copyright : (c) Ivan Perez, 2014-2022
-- (c) George Giorgidze, 2007-2012
-- (c) Henrik Nilsson, 2005-2006
-- (c) Antony Courtney and Henrik Nilsson, Yale University, 2003-2004
-- License : BSD-style (see the LICENSE file in the distribution)
--
-- Maintainer : ivan.perez@keera.co.uk
-- Stability : provisional
-- Portability : non-portable (GHC extensions)
--
-- Defines basic signal functions, and elementary ways of altering them.
--
-- This module defines very basic ways of creating and modifying signal
-- functions. In particular, it defines ways of creating constant output
-- producing SFs, and SFs that just pass the signal through unmodified.
--
-- It also defines ways of altering the input and the output signal only by
-- inserting one value in the signal, or by transforming it.
module FRP.BearRiver.Basic
(
-- * Basic signal functions
identity
, constant
-- ** Initialization
, (-->)
, (-:>)
, (>--)
, (-=>)
, (>=-)
, initially
)
where
-- External imports
import qualified Control.Category as Category
-- Internal imports (dunai)
import Data.MonadicStreamFunction.InternalCore (MSF (MSF, unMSF))
-- Internal imports
import FRP.BearRiver.InternalCore (SF, arr)
infixr 0 -->, -:>, >--, -=>, >=-
-- * Basic signal functions
-- | Identity: identity = arr id
--
-- Using 'identity' is preferred over lifting id, since the arrow combinators
-- know how to optimise certain networks based on the transformations being
-- applied.
identity :: Monad m => SF m a a
identity = Category.id
-- | Identity: constant b = arr (const b)
--
-- Using 'constant' is preferred over lifting const, since the arrow combinators
-- know how to optimise certain networks based on the transformations being
-- applied.
constant :: Monad m => b -> SF m a b
constant = arr . const
-- * Initialization
-- | Initialization operator (cf. Lustre/Lucid Synchrone).
--
-- The output at time zero is the first argument, and from that point on it
-- behaves like the signal function passed as second argument.
(-->) :: Monad m => b -> SF m a b -> SF m a b
b0 --> sf = MSF $ \a -> do
(_b, sf') <- unMSF sf a
return (b0, sf')
-- | Output pre-insert operator.
--
-- Insert a sample in the output, and from that point on, behave like the given
-- sf.
(-:>) :: Monad m => b -> SF m a b -> SF m a b
b -:> sf = MSF $ \_a -> return (b, sf)
-- | Input initialization operator.
--
-- The input at time zero is the first argument, and from that point on it
-- behaves like the signal function passed as second argument.
(>--) :: Monad m => a -> SF m a b -> SF m a b
a0 >-- sf = MSF $ \_ -> unMSF sf a0
-- | Transform initial output value.
--
-- Applies a transformation 'f' only to the first output value at time zero.
(-=>) :: Monad m => (b -> b) -> SF m a b -> SF m a b
f -=> sf = MSF $ \a -> do
(b, sf') <- unMSF sf a
return (f b, sf')
-- | Transform initial input value.
--
-- Applies a transformation 'f' only to the first input value at time zero.
(>=-) :: Monad m => (a -> a) -> SF m a b -> SF m a b
f >=- sf = MSF $ \a -> do
(b, sf') <- unMSF sf (f a)
return (b, sf')
-- | Override initial value of input signal.
initially :: Monad m => a -> SF m a a
initially = (--> identity)