module Util where import Control.Applicative import FRP.Elerea.Param -- Lifted conditional. ifS c s1 s2 = c >>= \b -> if b then s1 else s2 -- Override the first output of a signal. initSignal x s = do c <- stateful True (const (const False)) return $ ifS c (pure x) s scanM 0 _ _ = return [] scanM n f m = do x <- f m xs <- scanM (n-1) f x return (x:xs) -- Functions moved over from the old Experimental top module infix 4 ==@, /=@, <@, <=@, >=@, >@ infixr 3 &&@ infixr 2 ||@ infix 2 --> -- | The 'edge' transfer function takes a bool signal and emits -- another bool signal that turns true only at the moment when there -- is a rising edge on the input. edge :: Signal Bool -> SignalGen p (Signal Bool) edge b = delay True b >>= \db -> return $ (not <$> db) &&@ b -- | The '-->' transfer function behaves as a latch on a 'Maybe' -- input: it keeps its state when the input is 'Nothing', and replaces -- it with the input otherwise. (-->) :: a -- ^ Initial output -> Signal (Maybe a) -- ^ Maybe signal to latch on -> SignalGen p (Signal a) x0 --> s = transfer x0 store s where store _ Nothing x = x store _ (Just x) _ = x -- | Point-wise equality of two signals. (==@) :: Eq a => Signal a -> Signal a -> Signal Bool (==@) = liftA2 (==) -- | Point-wise inequality of two signals. (/=@) :: Eq a => Signal a -> Signal a -> Signal Bool (/=@) = liftA2 (/=) -- | Point-wise comparison of two signals. (<@) :: Ord a => Signal a -> Signal a -> Signal Bool (<@) = liftA2 (<) -- | Point-wise comparison of two signals. (<=@) :: Ord a => Signal a -> Signal a -> Signal Bool (<=@) = liftA2 (<=) -- | Point-wise comparison of two signals. (>=@) :: Ord a => Signal a -> Signal a -> Signal Bool (>=@) = liftA2 (>=) -- | Point-wise comparison of two signals. (>@) :: Ord a => Signal a -> Signal a -> Signal Bool (>@) = liftA2 (>) -- | Point-wise OR of two boolean signals. (||@) :: Signal Bool -> Signal Bool -> Signal Bool s1 ||@ s2 = s1 >>= \b -> if b then return True else s2 -- | Point-wise AND of two boolean signals. (&&@) :: Signal Bool -> Signal Bool -> Signal Bool s1 &&@ s2 = s1 >>= \b -> if b then s2 else return False