{-# OPTIONS_HADDOCK hide #-}
-----------------------------------------------------------------------------
-- |
-- Module  :  ForSyDe.Shallow.MoC.Synchronous.Lib
-- Copyright   :  (c) ForSyDe Group, KTH 2007-2008
-- License     :  BSD-style (see the file LICENSE)
-- 
-- Maintainer  :  forsyde-dev@ict.kth.se
-- Stability   :  experimental
-- Portability :  portable
--
-- This module contains the core library of the Synchronous MoC.
-----------------------------------------------------------------------------
module ForSyDe.Shallow.MoC.Synchronous.Lib (
  -- ** Combinational process constructors
  -- | Combinational process constructors are used for processes that
  --   do not have a state.
  mapSY, zipWithSY, zipWith3SY, 
  zipWith4SY, mapxSY, zipWithxSY,
  combSY, comb2SY, comb3SY, comb4SY,
  -- ** Sequential process constructors
  -- | Sequential process constructors are used for processes that
  --   have a state. One of the input parameters is the initial state.
  delaySY, delaynSY,
  scanlSY, scanl2SY, scanl3SY, scanldSY, scanld2SY,
  scanld3SY, mooreSY, moore2SY, moore3SY, mealySY,
  mealy2SY, mealy3SY, sourceSY, 
  filterSY, fillSY, holdSY,
  -- ** Synchronous Processes
  -- | The library contains a few simple processes that are applicable
  --   to many cases.
  whenSY, zipSY, zip3SY, zip4SY, zip5SY, zip6SY, 
  unzipSY, unzip3SY, unzip4SY, unzip5SY, unzip6SY,
  zipxSY, unzipxSY, 
  fstSY, sndSY
  ) where

import ForSyDe.Shallow.Core

----------------------------------------
-- COMBINATIONAL PROCESS CONSTRUCTORS --
----------------------------------------

-- | The process constructor 'mapSY' takes a combinational function as
-- argument and returns a process with one input signal and one output
-- signal.
--
-- >>> mapSY (+1) $ signal [1,2,3,4]
-- {2,3,4,5}
mapSY :: (a -> b) -> Signal a -> Signal b
mapSY :: (a -> b) -> Signal a -> Signal b
mapSY a -> b
_ Signal a
NullS   = Signal b
forall a. Signal a
NullS
mapSY a -> b
f (a
x:-Signal a
xs) = a -> b
f a
x b -> Signal b -> Signal b
forall a. a -> Signal a -> Signal a
:- ((a -> b) -> Signal a -> Signal b
forall a b. (a -> b) -> Signal a -> Signal b
mapSY a -> b
f Signal a
xs)
  
-- | The process constructor 'zipWithSY' takes a combinational
-- function as argument and returns a process with two input signals
-- and one output signal.
--
-- >>> zipWithSY (+) (signal [1,2,3,4]) (signal [11,12,13,14,15,16,17])
-- {12,14,16,18}
zipWithSY :: (a -> b -> c) -> Signal a -> Signal b -> Signal c
zipWithSY :: (a -> b -> c) -> Signal a -> Signal b -> Signal c
zipWithSY a -> b -> c
_ Signal a
NullS   Signal b
_   = Signal c
forall a. Signal a
NullS
zipWithSY a -> b -> c
_ Signal a
_   Signal b
NullS   = Signal c
forall a. Signal a
NullS
zipWithSY a -> b -> c
f (a
x:-Signal a
xs) (b
y:-Signal b
ys) = a -> b -> c
f a
x b
y c -> Signal c -> Signal c
forall a. a -> Signal a -> Signal a
:- ((a -> b -> c) -> Signal a -> Signal b -> Signal c
forall a b c. (a -> b -> c) -> Signal a -> Signal b -> Signal c
zipWithSY a -> b -> c
f Signal a
xs Signal b
ys)

-- | The process constructor 'zipWith3SY' takes a combinational
-- function as argument and returns a process with three input signals
-- and one output signal.
zipWith3SY :: (a -> b -> c -> d) -> Signal a -> Signal b -> Signal c -> Signal d
zipWith3SY :: (a -> b -> c -> d) -> Signal a -> Signal b -> Signal c -> Signal d
zipWith3SY a -> b -> c -> d
_ Signal a
NullS   Signal b
_   Signal c
_   = Signal d
forall a. Signal a
NullS
zipWith3SY a -> b -> c -> d
_ Signal a
_   Signal b
NullS   Signal c
_   = Signal d
forall a. Signal a
NullS
zipWith3SY a -> b -> c -> d
_ Signal a
_   Signal b
_   Signal c
NullS   = Signal d
forall a. Signal a
NullS
zipWith3SY a -> b -> c -> d
f (a
x:-Signal a
xs) (b
y:-Signal b
ys) (c
z:-Signal c
zs)
  = a -> b -> c -> d
f a
x b
y c
z d -> Signal d -> Signal d
forall a. a -> Signal a -> Signal a
:- ((a -> b -> c -> d) -> Signal a -> Signal b -> Signal c -> Signal d
forall a b c d.
(a -> b -> c -> d) -> Signal a -> Signal b -> Signal c -> Signal d
zipWith3SY a -> b -> c -> d
f Signal a
xs Signal b
ys Signal c
zs)

-- | The process constructor 'zipWith4SY' takes a combinational
-- function as argument and returns a process with four input signals
-- and one output signal.
zipWith4SY ::    (a -> b -> c -> d -> e) -> Signal a -> Signal b 
      -> Signal c -> Signal d -> Signal e
zipWith4SY :: (a -> b -> c -> d -> e)
-> Signal a -> Signal b -> Signal c -> Signal d -> Signal e
zipWith4SY a -> b -> c -> d -> e
_ Signal a
NullS   Signal b
_   Signal c
_   Signal d
_  = Signal e
forall a. Signal a
NullS
zipWith4SY a -> b -> c -> d -> e
_ Signal a
_   Signal b
NullS   Signal c
_   Signal d
_  = Signal e
forall a. Signal a
NullS
zipWith4SY a -> b -> c -> d -> e
_ Signal a
_   Signal b
_   Signal c
NullS   Signal d
_  = Signal e
forall a. Signal a
NullS
zipWith4SY a -> b -> c -> d -> e
_ Signal a
_   Signal b
_   Signal c
_   Signal d
NullS  = Signal e
forall a. Signal a
NullS
zipWith4SY a -> b -> c -> d -> e
f (a
w:-Signal a
ws) (b
x:-Signal b
xs) (c
y:-Signal c
ys) (d
z:-Signal d
zs) 
  = a -> b -> c -> d -> e
f a
w b
x c
y d
z e -> Signal e -> Signal e
forall a. a -> Signal a -> Signal a
:- ((a -> b -> c -> d -> e)
-> Signal a -> Signal b -> Signal c -> Signal d -> Signal e
forall a b c d e.
(a -> b -> c -> d -> e)
-> Signal a -> Signal b -> Signal c -> Signal d -> Signal e
zipWith4SY a -> b -> c -> d -> e
f Signal a
ws Signal b
xs Signal c
ys Signal d
zs)

-- | The process constructor 'combSY' is an alias to 'mapSY' and
-- behaves exactly in the same way.
combSY :: (a -> b) -> Signal a -> Signal b
combSY :: (a -> b) -> Signal a -> Signal b
combSY = (a -> b) -> Signal a -> Signal b
forall a b. (a -> b) -> Signal a -> Signal b
mapSY

-- | The process constructor 'comb2SY' is an alias to 'zipWithSY' and
-- behaves exactly in the same way.
comb2SY :: (a -> b -> c) -> Signal a -> Signal b -> Signal c
comb2SY :: (a -> b -> c) -> Signal a -> Signal b -> Signal c
comb2SY = (a -> b -> c) -> Signal a -> Signal b -> Signal c
forall a b c. (a -> b -> c) -> Signal a -> Signal b -> Signal c
zipWithSY
    
-- | The process constructor 'comb3SY' is an alias to 'zipWith3SY' and
-- behaves exactly in the same way.
comb3SY :: (a -> b -> c -> d) -> Signal a -> Signal b -> Signal c -> Signal d
comb3SY :: (a -> b -> c -> d) -> Signal a -> Signal b -> Signal c -> Signal d
comb3SY = (a -> b -> c -> d) -> Signal a -> Signal b -> Signal c -> Signal d
forall a b c d.
(a -> b -> c -> d) -> Signal a -> Signal b -> Signal c -> Signal d
zipWith3SY
    
-- | The process constructor 'comb4SY' is an alias to 'zipWith4SY' and
-- behaves exactly in the same way.
comb4SY :: (a -> b -> c -> d -> e) -> Signal a -> Signal b
    -> Signal c -> Signal d -> Signal e
comb4SY :: (a -> b -> c -> d -> e)
-> Signal a -> Signal b -> Signal c -> Signal d -> Signal e
comb4SY = (a -> b -> c -> d -> e)
-> Signal a -> Signal b -> Signal c -> Signal d -> Signal e
forall a b c d e.
(a -> b -> c -> d -> e)
-> Signal a -> Signal b -> Signal c -> Signal d -> Signal e
zipWith4SY
   
-- | The process constructor 'mapxSY' creates a process network that
-- maps a function onto all signals in a vector of signals. See 'mapV'.
--
-- >>> let s1 = signal [1,2,3,4]
-- >>> let s2 = signal [10,20,30,40]
-- >>> let s3 = signal [100,200,300]
-- >>> mapxSY (+1) $ vector [s1,s2,s3]
-- <{2,3,4,5},{11,21,31,41},{101,201,301}> 
mapxSY :: (a -> b) -> Vector (Signal a) -> Vector (Signal b)
mapxSY :: (a -> b) -> Vector (Signal a) -> Vector (Signal b)
mapxSY a -> b
f = (Signal a -> Signal b) -> Vector (Signal a) -> Vector (Signal b)
forall a b. (a -> b) -> Vector a -> Vector b
mapV ((a -> b) -> Signal a -> Signal b
forall a b. (a -> b) -> Signal a -> Signal b
mapSY a -> b
f)

-- | The process constructor 'zipWithxSY' works as 'zipWithSY', but
-- takes a vector of signals as input.
--
-- >>> let s1 = signal [1,2,3,4]
-- >>> let s2 = signal [10,20,30,40]
-- >>> let s3 = signal [100,200,300]
-- >>> zipWithxSY (reduceV (+)) $ vector [s1,s2,s3]
-- {111,222,333}
zipWithxSY :: (Vector a -> b) -> Vector (Signal a) -> Signal b
zipWithxSY :: (Vector a -> b) -> Vector (Signal a) -> Signal b
zipWithxSY Vector a -> b
f = (Vector a -> b) -> Signal (Vector a) -> Signal b
forall a b. (a -> b) -> Signal a -> Signal b
mapSY Vector a -> b
f (Signal (Vector a) -> Signal b)
-> (Vector (Signal a) -> Signal (Vector a))
-> Vector (Signal a)
-> Signal b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Vector (Signal a) -> Signal (Vector a)
forall a. Vector (Signal a) -> Signal (Vector a)
zipxSY

-------------------------------------
-- SEQUENTIAL PROCESS CONSTRUCTORS --
-------------------------------------

-- | The process constructor 'delaySY' delays the signal one event
-- cycle by introducing an initial value at the beginning of the
-- output signal.  Note, that this implies that there is one event
-- (the first) at the output signal that has no corresponding event at
-- the input signal.  One could argue that input and output signals
-- are not fully synchronized, even though all input events are
-- synchronous with a corresponding output event. However, this is
-- necessary to initialize feed-back loops.
--
-- >>> delaySY 1 $ signal [1,2,3,4]
-- {1,1,2,3,4}
delaySY :: a        -- ^Initial state
        -> Signal a -- ^Input signal
        -> Signal a -- ^Output signal
delaySY :: a -> Signal a -> Signal a
delaySY a
e Signal a
es = a
ea -> Signal a -> Signal a
forall a. a -> Signal a -> Signal a
:-Signal a
es

-- | The process constructor 'delaynSY' delays the signal n events by
-- introducing n identical default values.
--
-- >>> delaynSY 0 3 $ signal [1,2,3,4]
-- {0,0,0,1,2,3,4}
delaynSY :: a        -- ^Initial state
         -> Int      -- ^ Delay cycles 
         -> Signal a -- ^Input signal
         -> Signal a -- ^Output signal
delaynSY :: a -> Int -> Signal a -> Signal a
delaynSY a
e Int
n Signal a
xs | Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
0 = Signal a
xs
                | Bool
otherwise = a
e a -> Signal a -> Signal a
forall a. a -> Signal a -> Signal a
:- a -> Int -> Signal a -> Signal a
forall a. a -> Int -> Signal a -> Signal a
delaynSY a
e (Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) Signal a
xs 

-- | The process constructor 'scanlSY' is used to construct a finite
-- state machine process without output decoder. It takes an initial
-- value and a function for the next state decoder. The process
-- constructor behaves similar to the Haskell prelude function
-- 'scanlSY' and has the value of the new state as its output value as
-- illustrated by the following example.
--
-- >>> scanlSY (+) 0 (signal [1,2,3,4])
-- {1,3,6,10}
-- 
-- This is in contrast to the function 'scanldSY', which has its
-- current state as its output value.
scanlSY :: (a -> b -> a) -- ^Combinational function for next state
                         -- decoder
       -> a              -- ^Initial state
       -> Signal b       -- ^ Input signal 
       -> Signal a       -- ^ Output signal
scanlSY :: (a -> b -> a) -> a -> Signal b -> Signal a
scanlSY a -> b -> a
f a
mem Signal b
xs = Signal a
s'
  where s' :: Signal a
s' = (a -> b -> a) -> Signal a -> Signal b -> Signal a
forall a b c. (a -> b -> c) -> Signal a -> Signal b -> Signal c
zipWithSY a -> b -> a
f (a -> Signal a -> Signal a
forall a. a -> Signal a -> Signal a
delaySY a
mem Signal a
s') Signal b
xs 

-- | The process constructor 'scanl2SY' behaves like 'scanlSY', but
-- has two input signals.
scanl2SY :: (a -> b -> c -> a) -> a -> Signal b -> Signal c -> Signal a
scanl2SY :: (a -> b -> c -> a) -> a -> Signal b -> Signal c -> Signal a
scanl2SY a -> b -> c -> a
f a
mem Signal b
xs Signal c
ys = Signal a
s'
  where s' :: Signal a
s' = (a -> b -> c -> a) -> Signal a -> Signal b -> Signal c -> Signal a
forall a b c d.
(a -> b -> c -> d) -> Signal a -> Signal b -> Signal c -> Signal d
zipWith3SY a -> b -> c -> a
f (a -> Signal a -> Signal a
forall a. a -> Signal a -> Signal a
delaySY a
mem Signal a
s') Signal b
xs Signal c
ys

-- | The process constructor 'scanl3SY' behaves like 'scanlSY', but
-- has three input signals.
scanl3SY :: (a -> b -> c -> d -> a) -> a -> Signal b
         -> Signal c -> Signal d -> Signal a
scanl3SY :: (a -> b -> c -> d -> a)
-> a -> Signal b -> Signal c -> Signal d -> Signal a
scanl3SY a -> b -> c -> d -> a
f a
mem Signal b
xs Signal c
ys Signal d
zs = Signal a
s'
  where s' :: Signal a
s' = (a -> b -> c -> d -> a)
-> Signal a -> Signal b -> Signal c -> Signal d -> Signal a
forall a b c d e.
(a -> b -> c -> d -> e)
-> Signal a -> Signal b -> Signal c -> Signal d -> Signal e
zipWith4SY a -> b -> c -> d -> a
f (a -> Signal a -> Signal a
forall a. a -> Signal a -> Signal a
delaySY a
mem Signal a
s') Signal b
xs Signal c
ys Signal d
zs

-- | The process constructor 'scanldSY' is used to construct a finite
-- state machine process without output decoder. It takes an initial
-- value and a function for the next state decoder. The process
-- constructor behaves similar to the Haskell prelude function
-- 'scanlSY'. In contrast to the process constructor 'scanlSY' here
-- the output value is the current state and not the one of the next
-- state.
--
-- >>> scanldSY (+) 0 (signal [1,2,3,4])
-- {0,1,3,6,10}
scanldSY :: (a -> b -> a) -- ^Combinational function for next state
                          -- decoder
    -> a                  -- ^Initial state
    -> Signal b           -- ^ Input signal
    -> Signal a           -- ^ Output signal
scanldSY :: (a -> b -> a) -> a -> Signal b -> Signal a
scanldSY a -> b -> a
f a
mem Signal b
xs = Signal a
s'
    where s' :: Signal a
s' = a -> Signal a -> Signal a
forall a. a -> Signal a -> Signal a
delaySY a
mem (Signal a -> Signal a) -> Signal a -> Signal a
forall a b. (a -> b) -> a -> b
$ (a -> b -> a) -> Signal a -> Signal b -> Signal a
forall a b c. (a -> b -> c) -> Signal a -> Signal b -> Signal c
zipWithSY a -> b -> a
f Signal a
s' Signal b
xs 

-- | The process constructor 'scanld2SY' behaves like 'scanldSY', but
-- has two input signals.
scanld2SY ::    (a -> b -> c -> a) -> a -> Signal b -> Signal c 
     -> Signal a
scanld2SY :: (a -> b -> c -> a) -> a -> Signal b -> Signal c -> Signal a
scanld2SY a -> b -> c -> a
f a
mem Signal b
xs Signal c
ys = Signal a
s'
    where s' :: Signal a
s' = a -> Signal a -> Signal a
forall a. a -> Signal a -> Signal a
delaySY a
mem (Signal a -> Signal a) -> Signal a -> Signal a
forall a b. (a -> b) -> a -> b
$ (a -> b -> c -> a) -> Signal a -> Signal b -> Signal c -> Signal a
forall a b c d.
(a -> b -> c -> d) -> Signal a -> Signal b -> Signal c -> Signal d
zipWith3SY a -> b -> c -> a
f Signal a
s' Signal b
xs Signal c
ys

-- | The process constructor 'scanld3SY' behaves like 'scanldSY', but has three input signals.
scanld3SY :: (a -> b -> c -> d -> a) -> a -> Signal b 
          -> Signal c -> Signal d -> Signal a
scanld3SY :: (a -> b -> c -> d -> a)
-> a -> Signal b -> Signal c -> Signal d -> Signal a
scanld3SY a -> b -> c -> d -> a
f a
mem Signal b
xs Signal c
ys Signal d
zs = Signal a
s'
  where s' :: Signal a
s' = a -> Signal a -> Signal a
forall a. a -> Signal a -> Signal a
delaySY a
mem (Signal a -> Signal a) -> Signal a -> Signal a
forall a b. (a -> b) -> a -> b
$ (a -> b -> c -> d -> a)
-> Signal a -> Signal b -> Signal c -> Signal d -> Signal a
forall a b c d e.
(a -> b -> c -> d -> e)
-> Signal a -> Signal b -> Signal c -> Signal d -> Signal e
zipWith4SY a -> b -> c -> d -> a
f Signal a
s' Signal b
xs Signal c
ys Signal d
zs

-- | The process constructor 'mooreSY' is used to model state machines
-- of \"Moore\" type, where the output only depends on the current
-- state. The process constructor is based on the process constructor
-- 'scanldSY', since it is natural for state machines in hardware,
-- that the output operates on the current state and not on the next
-- state. The process constructors takes a function to calculate the
-- next state, another function to calculate the output and a value
-- for the initial state.
--
-- In contrast the output of a process created by the process constructor 'mealySY' depends not only on the state, but also on the input values.
--
-- >>> mooreSY (+) (*2) 0 $ signal [1,2,3,4,5]
-- {0,2,6,12,20,30}
mooreSY :: (a -> b -> a) -- ^Combinational function for next state
                         -- decoder
        -> (a -> c)      -- ^Combinational function for output decoder
        -> a             -- ^Initial state
        -> Signal b      -- ^Input signal
        -> Signal c      -- ^Output signal
mooreSY :: (a -> b -> a) -> (a -> c) -> a -> Signal b -> Signal c
mooreSY a -> b -> a
nextState a -> c
output a
initial 
    = (a -> c) -> Signal a -> Signal c
forall a b. (a -> b) -> Signal a -> Signal b
mapSY a -> c
output (Signal a -> Signal c)
-> (Signal b -> Signal a) -> Signal b -> Signal c
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((a -> b -> a) -> a -> Signal b -> Signal a
forall a b. (a -> b -> a) -> a -> Signal b -> Signal a
scanldSY a -> b -> a
nextState a
initial)

-- | The process constructor 'moore2SY' behaves like 'mooreSY', but
-- has two input signals.
moore2SY ::   (a -> b -> c -> a) -> (a -> d) -> a -> Signal b 
         -> Signal c -> Signal d
moore2SY :: (a -> b -> c -> a)
-> (a -> d) -> a -> Signal b -> Signal c -> Signal d
moore2SY a -> b -> c -> a
nextState a -> d
output a
initial Signal b
inp1 Signal c
inp2 =
  (a -> d) -> Signal a -> Signal d
forall a b. (a -> b) -> Signal a -> Signal b
mapSY a -> d
output ((a -> b -> c -> a) -> a -> Signal b -> Signal c -> Signal a
forall a b c.
(a -> b -> c -> a) -> a -> Signal b -> Signal c -> Signal a
scanld2SY a -> b -> c -> a
nextState a
initial Signal b
inp1 Signal c
inp2)

-- | The process constructor 'moore3SY' behaves like 'mooreSY', but
-- has three input signals.
moore3SY :: (a -> b -> c -> d -> a) -> (a -> e) -> a -> Signal b 
         -> Signal c -> Signal d -> Signal e
moore3SY :: (a -> b -> c -> d -> a)
-> (a -> e) -> a -> Signal b -> Signal c -> Signal d -> Signal e
moore3SY a -> b -> c -> d -> a
nextState a -> e
output a
initial Signal b
inp1 Signal c
inp2 Signal d
inp3 =
  (a -> e) -> Signal a -> Signal e
forall a b. (a -> b) -> Signal a -> Signal b
mapSY a -> e
output ((a -> b -> c -> d -> a)
-> a -> Signal b -> Signal c -> Signal d -> Signal a
forall a b c d.
(a -> b -> c -> d -> a)
-> a -> Signal b -> Signal c -> Signal d -> Signal a
scanld3SY a -> b -> c -> d -> a
nextState a
initial Signal b
inp1 Signal c
inp2 Signal d
inp3)

-- | The process constructor 'melaySY' is used to model state machines
-- of \"Mealy\" type, where the output only depends on the current
-- state and the input values. The process constructor is based on the
-- process constructor 'scanldSY', since it is natural for state
-- machines in hardware, that the output operates on the current state
-- and not on the next state. The process constructors takes a
-- function to calculate the next state, another function to calculate
-- the output and a value for the initial state.
--
-- In contrast the output of a process created by the process
-- constructor 'mooreSY' depends only on the state, but not on the
-- input values.
--
-- >>> mealySY (+) (+) 0 $ signal [1,2,3,4,5]
-- {1,3,6,10,15}
mealySY :: (a -> b -> a) -- ^Combinational function for next state
                         -- decoder
       -> (a -> b -> c)  -- ^Combinational function for output decoder
       -> a              -- ^Initial state
       -> Signal b       -- ^Input signal 
       -> Signal c       -- ^Output signal
mealySY :: (a -> b -> a) -> (a -> b -> c) -> a -> Signal b -> Signal c
mealySY a -> b -> a
nextState a -> b -> c
output a
initial Signal b
sig =
  (a -> b -> c) -> Signal a -> Signal b -> Signal c
forall a b c. (a -> b -> c) -> Signal a -> Signal b -> Signal c
zipWithSY a -> b -> c
output Signal a
state Signal b
sig
  where state :: Signal a
state = (a -> b -> a) -> a -> Signal b -> Signal a
forall a b. (a -> b -> a) -> a -> Signal b -> Signal a
scanldSY a -> b -> a
nextState a
initial Signal b
sig

-- | The process constructor 'mealy2SY' behaves like 'mealySY', but
-- has two input signals.
mealy2SY :: (a -> b -> c -> a) -> (a -> b -> c -> d) -> a
         -> Signal b -> Signal c -> Signal d
mealy2SY :: (a -> b -> c -> a)
-> (a -> b -> c -> d) -> a -> Signal b -> Signal c -> Signal d
mealy2SY a -> b -> c -> a
nextState a -> b -> c -> d
output a
initial Signal b
inp1 Signal c
inp2 =
  (a -> b -> c -> d) -> Signal a -> Signal b -> Signal c -> Signal d
forall a b c d.
(a -> b -> c -> d) -> Signal a -> Signal b -> Signal c -> Signal d
zipWith3SY a -> b -> c -> d
output ((a -> b -> c -> a) -> a -> Signal b -> Signal c -> Signal a
forall a b c.
(a -> b -> c -> a) -> a -> Signal b -> Signal c -> Signal a
scanld2SY a -> b -> c -> a
nextState a
initial Signal b
inp1 Signal c
inp2) Signal b
inp1 Signal c
inp2  

-- | The process constructor 'mealy3SY' behaves like 'mealySY', but
-- has three input signals.
mealy3SY :: (a -> b -> c -> d -> a) -> (a -> b -> c -> d -> e) -> a
         -> Signal b -> Signal c -> Signal d -> Signal e
mealy3SY :: (a -> b -> c -> d -> a)
-> (a -> b -> c -> d -> e)
-> a
-> Signal b
-> Signal c
-> Signal d
-> Signal e
mealy3SY a -> b -> c -> d -> a
nextState a -> b -> c -> d -> e
output a
initial Signal b
inp1 Signal c
inp2 Signal d
inp3 =
  (a -> b -> c -> d -> e)
-> Signal a -> Signal b -> Signal c -> Signal d -> Signal e
forall a b c d e.
(a -> b -> c -> d -> e)
-> Signal a -> Signal b -> Signal c -> Signal d -> Signal e
zipWith4SY a -> b -> c -> d -> e
output ((a -> b -> c -> d -> a)
-> a -> Signal b -> Signal c -> Signal d -> Signal a
forall a b c d.
(a -> b -> c -> d -> a)
-> a -> Signal b -> Signal c -> Signal d -> Signal a
scanld3SY a -> b -> c -> d -> a
nextState a
initial Signal b
inp1 Signal c
inp2 Signal d
inp3) Signal b
inp1 Signal c
inp2 Signal d
inp3 

-- | The process constructor 'filterSY' discards the values who do not
-- fulfill a predicate given by a predicate function and replaces them
-- with absent events.
filterSY :: (a -> Bool)        -- ^Predicate function
         -> Signal a           -- ^Input signal
         -> Signal (AbstExt a) -- ^Output signal
filterSY :: (a -> Bool) -> Signal a -> Signal (AbstExt a)
filterSY a -> Bool
_ Signal a
NullS   = Signal (AbstExt a)
forall a. Signal a
NullS
filterSY a -> Bool
p (a
x:-Signal a
xs) = if (a -> Bool
p a
x Bool -> Bool -> Bool
forall a. Eq a => a -> a -> Bool
== Bool
True) then
                       a -> AbstExt a
forall a. a -> AbstExt a
Prst a
x AbstExt a -> Signal (AbstExt a) -> Signal (AbstExt a)
forall a. a -> Signal a -> Signal a
:- (a -> Bool) -> Signal a -> Signal (AbstExt a)
forall a. (a -> Bool) -> Signal a -> Signal (AbstExt a)
filterSY a -> Bool
p Signal a
xs
                     else
                       AbstExt a
forall a. AbstExt a
Abst AbstExt a -> Signal (AbstExt a) -> Signal (AbstExt a)
forall a. a -> Signal a -> Signal a
:- (a -> Bool) -> Signal a -> Signal (AbstExt a)
forall a. (a -> Bool) -> Signal a -> Signal (AbstExt a)
filterSY a -> Bool
p Signal a
xs

-- | The process 'sourceSY' takes a function and an initial state and
-- generates an infinite signal starting with the initial state as
-- first output followed by the recursive application of the function
-- on the current state. The state also serves as output value.
--
-- The process that has the infinite signal of natural numbers as
-- output is constructed by
--
-- >>> takeS 5 $ sourceSY (+1) 0
-- {0,1,2,3,4}
sourceSY :: (a -> a) -> a -> Signal a
sourceSY :: (a -> a) -> a -> Signal a
sourceSY a -> a
f a
s0 = Signal a
o
   where o :: Signal a
o = a -> Signal a -> Signal a
forall a. a -> Signal a -> Signal a
delaySY a
s0 Signal a
s
         s :: Signal a
s = (a -> a) -> Signal a -> Signal a
forall a b. (a -> b) -> Signal a -> Signal b
mapSY a -> a
f Signal a
o

-- | The process constructor 'fillSY' creates a process that 'fills' a
-- signal with present values by replacing absent values with a given
-- value. The output signal is not any more of the type 'AbstExt'.
--
-- >>> let s = signal [Abst, Prst 1, Prst 2, Abst, Abst, Prst 4, Abst]
-- >>> fillSY 3 s
-- {3,1,2,3,3,4,3}
fillSY :: a                  -- ^Default value
       -> Signal (AbstExt a) -- ^Absent extended input signal
       -> Signal a           -- ^Output signal
fillSY :: a -> Signal (AbstExt a) -> Signal a
fillSY a
a Signal (AbstExt a)
xs = (AbstExt a -> a) -> Signal (AbstExt a) -> Signal a
forall a b. (a -> b) -> Signal a -> Signal b
mapSY (a -> AbstExt a -> a
forall p. p -> AbstExt p -> p
replaceAbst a
a) Signal (AbstExt a)
xs
      where replaceAbst :: p -> AbstExt p -> p
replaceAbst p
a' AbstExt p
Abst     = p
a'
            replaceAbst p
_  (Prst p
x) = p
x

-- | The process constructor 'holdSY' creates a process that 'fills' a signal with values by replacing absent values by the preceding present value. Only in cases, where no preceding value exists, the absent value is replaced by a default value. The output signal is not any more of the type 'AbstExt'.
--
-- >>> let s = signal [Abst, Prst 1, Prst 2, Abst, Abst, Prst 4, Abst]
-- >>> holdSY 3 s
-- {3,1,2,2,2,4,4}
holdSY :: a                  -- ^Default value
       -> Signal (AbstExt a) -- ^Absent extended input signal
       -> Signal a           -- ^Output signal
holdSY :: a -> Signal (AbstExt a) -> Signal a
holdSY a
a Signal (AbstExt a)
xs = (a -> AbstExt a -> a) -> a -> Signal (AbstExt a) -> Signal a
forall a b. (a -> b -> a) -> a -> Signal b -> Signal a
scanlSY a -> AbstExt a -> a
forall p. p -> AbstExt p -> p
hold a
a Signal (AbstExt a)
xs
      where hold :: p -> AbstExt p -> p
hold p
a' AbstExt p
Abst     = p
a'
            hold p
_  (Prst p
x) = p
x

---------------------------
-- SYNCHRONOUS PROCESSES --
---------------------------

-- | The process constructor 'whenSY' creates a process that
-- synchronizes a signal of absent extended values with another signal
-- of absent extended values. The output signal has the value of the
-- first signal whenever an event has a present value and 'Abst' when
-- the event has an absent value.
--
-- >>> let clk = signal [Abst,    Prst (), Prst (), Abst,    Abst,    Prst (), Abst]
-- >>> let sig = signal [Prst 10, Prst 11, Prst 12, Prst 13, Prst 14, Prst 15]
-- >>> sig `whenSY` clk
-- {_,11,12,_,_,15}
whenSY :: Signal (AbstExt a) -> Signal (AbstExt b) 
       -> Signal (AbstExt a)
whenSY :: Signal (AbstExt a) -> Signal (AbstExt b) -> Signal (AbstExt a)
whenSY Signal (AbstExt a)
NullS   Signal (AbstExt b)
_          = Signal (AbstExt a)
forall a. Signal a
NullS
whenSY Signal (AbstExt a)
_       Signal (AbstExt b)
NullS      = Signal (AbstExt a)
forall a. Signal a
NullS
whenSY (AbstExt a
_:-Signal (AbstExt a)
xs) (AbstExt b
Abst:-Signal (AbstExt b)
ys) = AbstExt a
forall a. AbstExt a
Abst AbstExt a -> Signal (AbstExt a) -> Signal (AbstExt a)
forall a. a -> Signal a -> Signal a
:- (Signal (AbstExt a) -> Signal (AbstExt b) -> Signal (AbstExt a)
forall a b.
Signal (AbstExt a) -> Signal (AbstExt b) -> Signal (AbstExt a)
whenSY Signal (AbstExt a)
xs Signal (AbstExt b)
ys)
whenSY (AbstExt a
x:-Signal (AbstExt a)
xs) (AbstExt b
_:-Signal (AbstExt b)
ys)    = AbstExt a
x    AbstExt a -> Signal (AbstExt a) -> Signal (AbstExt a)
forall a. a -> Signal a -> Signal a
:- (Signal (AbstExt a) -> Signal (AbstExt b) -> Signal (AbstExt a)
forall a b.
Signal (AbstExt a) -> Signal (AbstExt b) -> Signal (AbstExt a)
whenSY Signal (AbstExt a)
xs Signal (AbstExt b)
ys)

-- | The process 'zipSY' \"zips\" two incoming signals into one signal
-- of tuples.
--
-- >>> zipSY (signal [1,2,3,4]) (signal [10,11,12,13,14])
-- {(1,10),(2,11),(3,12),(4,13)}
zipSY :: Signal a -> Signal b -> Signal (a,b)
zipSY :: Signal a -> Signal b -> Signal (a, b)
zipSY (a
x:-Signal a
xs) (b
y:-Signal b
ys) = (a
x, b
y) (a, b) -> Signal (a, b) -> Signal (a, b)
forall a. a -> Signal a -> Signal a
:- Signal a -> Signal b -> Signal (a, b)
forall a b. Signal a -> Signal b -> Signal (a, b)
zipSY Signal a
xs Signal b
ys
zipSY Signal a
_       Signal b
_       = Signal (a, b)
forall a. Signal a
NullS

-- | The process 'zip3SY' works as 'zipSY', but takes three input
-- signals.
-- 
zip3SY :: Signal a -> Signal b -> Signal c -> Signal (a,b,c)
zip3SY :: Signal a -> Signal b -> Signal c -> Signal (a, b, c)
zip3SY (a
x:-Signal a
xs) (b
y:-Signal b
ys) (c
z:-Signal c
zs) = (a
x, b
y, c
z) (a, b, c) -> Signal (a, b, c) -> Signal (a, b, c)
forall a. a -> Signal a -> Signal a
:- Signal a -> Signal b -> Signal c -> Signal (a, b, c)
forall a b c. Signal a -> Signal b -> Signal c -> Signal (a, b, c)
zip3SY Signal a
xs Signal b
ys Signal c
zs
zip3SY Signal a
_       Signal b
_       Signal c
_       = Signal (a, b, c)
forall a. Signal a
NullS

-- | The process 'zip4SY' works as 'zipSY', but takes four input
-- signals.
zip4SY ::    Signal a -> Signal b -> Signal c -> Signal d 
      -> Signal (a,b,c,d)
zip4SY :: Signal a -> Signal b -> Signal c -> Signal d -> Signal (a, b, c, d)
zip4SY (a
w:-Signal a
ws) (b
x:-Signal b
xs) (c
y:-Signal c
ys) (d
z:-Signal d
zs)
  = (a
w, b
x, c
y, d
z) (a, b, c, d) -> Signal (a, b, c, d) -> Signal (a, b, c, d)
forall a. a -> Signal a -> Signal a
:- Signal a -> Signal b -> Signal c -> Signal d -> Signal (a, b, c, d)
forall a b c d.
Signal a -> Signal b -> Signal c -> Signal d -> Signal (a, b, c, d)
zip4SY Signal a
ws Signal b
xs Signal c
ys Signal d
zs
zip4SY Signal a
_ Signal b
_ Signal c
_ Signal d
_ = Signal (a, b, c, d)
forall a. Signal a
NullS

-- | The process 'zip5SY' works as 'zipSY', but takes four input
-- signals.
zip5SY :: Signal a -> Signal b -> Signal c -> Signal d -> Signal e
       -> Signal (a,b,c,d,e)
zip5SY :: Signal a
-> Signal b
-> Signal c
-> Signal d
-> Signal e
-> Signal (a, b, c, d, e)
zip5SY (a
x1:-Signal a
x1s) (b
x2:-Signal b
x2s) (c
x3:-Signal c
x3s) (d
x4:-Signal d
x4s) (e
x5:-Signal e
x5s) 
  = (a
x1,b
x2,c
x3,d
x4,e
x5) (a, b, c, d, e) -> Signal (a, b, c, d, e) -> Signal (a, b, c, d, e)
forall a. a -> Signal a -> Signal a
:- Signal a
-> Signal b
-> Signal c
-> Signal d
-> Signal e
-> Signal (a, b, c, d, e)
forall a b c d e.
Signal a
-> Signal b
-> Signal c
-> Signal d
-> Signal e
-> Signal (a, b, c, d, e)
zip5SY Signal a
x1s Signal b
x2s Signal c
x3s Signal d
x4s Signal e
x5s
zip5SY Signal a
_ Signal b
_ Signal c
_ Signal d
_ Signal e
_ = Signal (a, b, c, d, e)
forall a. Signal a
NullS

-- | The process 'zip6SY' works as 'zipSY', but takes four input
-- signals.
zip6SY :: Signal a -> Signal b -> Signal c -> Signal d -> Signal e
       -> Signal f -> Signal (a,b,c,d,e,f)
zip6SY :: Signal a
-> Signal b
-> Signal c
-> Signal d
-> Signal e
-> Signal f
-> Signal (a, b, c, d, e, f)
zip6SY (a
x1:-Signal a
x1s) (b
x2:-Signal b
x2s) (c
x3:-Signal c
x3s) (d
x4:-Signal d
x4s) (e
x5:-Signal e
x5s)  (f
x6:-Signal f
x6s) 
    = (a
x1,b
x2,c
x3,d
x4,e
x5,f
x6) (a, b, c, d, e, f)
-> Signal (a, b, c, d, e, f) -> Signal (a, b, c, d, e, f)
forall a. a -> Signal a -> Signal a
:- Signal a
-> Signal b
-> Signal c
-> Signal d
-> Signal e
-> Signal f
-> Signal (a, b, c, d, e, f)
forall a b c d e f.
Signal a
-> Signal b
-> Signal c
-> Signal d
-> Signal e
-> Signal f
-> Signal (a, b, c, d, e, f)
zip6SY Signal a
x1s Signal b
x2s Signal c
x3s Signal d
x4s Signal e
x5s Signal f
x6s
zip6SY Signal a
_ Signal b
_ Signal c
_ Signal d
_ Signal e
_ Signal f
_ = Signal (a, b, c, d, e, f)
forall a. Signal a
NullS

-- | The process 'unzipSY' \"unzips\" a signal of tuples into two
-- signals.
unzipSY :: Signal (a,b) -> (Signal a,Signal b)
unzipSY :: Signal (a, b) -> (Signal a, Signal b)
unzipSY Signal (a, b)
NullS         = (Signal a
forall a. Signal a
NullS, Signal b
forall a. Signal a
NullS)
unzipSY ((a
x, b
y):-Signal (a, b)
xys) = (a
xa -> Signal a -> Signal a
forall a. a -> Signal a -> Signal a
:-Signal a
xs, b
yb -> Signal b -> Signal b
forall a. a -> Signal a -> Signal a
:-Signal b
ys)
  where (Signal a
xs, Signal b
ys) = Signal (a, b) -> (Signal a, Signal b)
forall a b. Signal (a, b) -> (Signal a, Signal b)
unzipSY Signal (a, b)
xys

-- | The process 'unzip3SY' works as 'unzipSY', but has three output
-- signals.
unzip3SY :: Signal (a, b, c) -> (Signal a, Signal b, Signal c)
unzip3SY :: Signal (a, b, c) -> (Signal a, Signal b, Signal c)
unzip3SY Signal (a, b, c)
NullS             = (Signal a
forall a. Signal a
NullS, Signal b
forall a. Signal a
NullS, Signal c
forall a. Signal a
NullS)
unzip3SY ((a
x, b
y, c
z):-Signal (a, b, c)
xyzs) = (a
xa -> Signal a -> Signal a
forall a. a -> Signal a -> Signal a
:-Signal a
xs, b
yb -> Signal b -> Signal b
forall a. a -> Signal a -> Signal a
:-Signal b
ys, c
zc -> Signal c -> Signal c
forall a. a -> Signal a -> Signal a
:-Signal c
zs)
  where (Signal a
xs, Signal b
ys, Signal c
zs) = Signal (a, b, c) -> (Signal a, Signal b, Signal c)
forall a b c. Signal (a, b, c) -> (Signal a, Signal b, Signal c)
unzip3SY Signal (a, b, c)
xyzs

-- | The process 'unzip4SY' works as 'unzipSY', but has four output
-- signals.
unzip4SY :: Signal (a,b,c,d) 
         -> (Signal a,Signal b,Signal c,Signal d)
unzip4SY :: Signal (a, b, c, d) -> (Signal a, Signal b, Signal c, Signal d)
unzip4SY Signal (a, b, c, d)
NullS      = (Signal a
forall a. Signal a
NullS, Signal b
forall a. Signal a
NullS, Signal c
forall a. Signal a
NullS, Signal d
forall a. Signal a
NullS)
unzip4SY ((a
w,b
x,c
y,d
z):-Signal (a, b, c, d)
wxyzs) = (a
wa -> Signal a -> Signal a
forall a. a -> Signal a -> Signal a
:-Signal a
ws, b
xb -> Signal b -> Signal b
forall a. a -> Signal a -> Signal a
:-Signal b
xs, c
yc -> Signal c -> Signal c
forall a. a -> Signal a -> Signal a
:-Signal c
ys, d
zd -> Signal d -> Signal d
forall a. a -> Signal a -> Signal a
:-Signal d
zs)
  where (Signal a
ws, Signal b
xs, Signal c
ys, Signal d
zs) = Signal (a, b, c, d) -> (Signal a, Signal b, Signal c, Signal d)
forall a b c d.
Signal (a, b, c, d) -> (Signal a, Signal b, Signal c, Signal d)
unzip4SY Signal (a, b, c, d)
wxyzs

-- | The process 'unzip5SY' works as 'unzipSY', but has four output
-- signals.
unzip5SY :: Signal (a,b,c,d,e) 
         -> (Signal a,Signal b,Signal c,Signal d,Signal e)
unzip5SY :: Signal (a, b, c, d, e)
-> (Signal a, Signal b, Signal c, Signal d, Signal e)
unzip5SY Signal (a, b, c, d, e)
NullS                  = (Signal a
forall a. Signal a
NullS, Signal b
forall a. Signal a
NullS, Signal c
forall a. Signal a
NullS, Signal d
forall a. Signal a
NullS,Signal e
forall a. Signal a
NullS)
unzip5SY ((a
x1,b
x2,c
x3,d
x4,e
x5):-Signal (a, b, c, d, e)
xs) = (a
x1a -> Signal a -> Signal a
forall a. a -> Signal a -> Signal a
:-Signal a
x1s, b
x2b -> Signal b -> Signal b
forall a. a -> Signal a -> Signal a
:-Signal b
x2s, c
x3c -> Signal c -> Signal c
forall a. a -> Signal a -> Signal a
:-Signal c
x3s, d
x4d -> Signal d -> Signal d
forall a. a -> Signal a -> Signal a
:-Signal d
x4s, e
x5e -> Signal e -> Signal e
forall a. a -> Signal a -> Signal a
:-Signal e
x5s)
  where (Signal a
x1s, Signal b
x2s, Signal c
x3s, Signal d
x4s,Signal e
x5s) = Signal (a, b, c, d, e)
-> (Signal a, Signal b, Signal c, Signal d, Signal e)
forall a b c d e.
Signal (a, b, c, d, e)
-> (Signal a, Signal b, Signal c, Signal d, Signal e)
unzip5SY Signal (a, b, c, d, e)
xs

-- | The process 'unzip6SY' works as 'unzipSY', but has four output
-- signals.
unzip6SY :: Signal (a,b,c,d,e,f) 
    -> (Signal a,Signal b,Signal c,Signal d,Signal e,Signal f)
unzip6SY :: Signal (a, b, c, d, e, f)
-> (Signal a, Signal b, Signal c, Signal d, Signal e, Signal f)
unzip6SY Signal (a, b, c, d, e, f)
NullS = (Signal a
forall a. Signal a
NullS, Signal b
forall a. Signal a
NullS, Signal c
forall a. Signal a
NullS, Signal d
forall a. Signal a
NullS,Signal e
forall a. Signal a
NullS,Signal f
forall a. Signal a
NullS)
unzip6SY ((a
x1,b
x2,c
x3,d
x4,e
x5,f
x6):-Signal (a, b, c, d, e, f)
xs) 
  = (a
x1a -> Signal a -> Signal a
forall a. a -> Signal a -> Signal a
:-Signal a
x1s, b
x2b -> Signal b -> Signal b
forall a. a -> Signal a -> Signal a
:-Signal b
x2s, c
x3c -> Signal c -> Signal c
forall a. a -> Signal a -> Signal a
:-Signal c
x3s, d
x4d -> Signal d -> Signal d
forall a. a -> Signal a -> Signal a
:-Signal d
x4s, e
x5e -> Signal e -> Signal e
forall a. a -> Signal a -> Signal a
:-Signal e
x5s, f
x6f -> Signal f -> Signal f
forall a. a -> Signal a -> Signal a
:-Signal f
x6s)
  where (Signal a
x1s, Signal b
x2s, Signal c
x3s, Signal d
x4s, Signal e
x5s, Signal f
x6s) = Signal (a, b, c, d, e, f)
-> (Signal a, Signal b, Signal c, Signal d, Signal e, Signal f)
forall a b c d e f.
Signal (a, b, c, d, e, f)
-> (Signal a, Signal b, Signal c, Signal d, Signal e, Signal f)
unzip6SY Signal (a, b, c, d, e, f)
xs

-- | The process 'zipxSY' transposes a signal of vectors into a vector
-- of signals. All the events carried by the output signal are synchronized values from all input signals.
--
-- >>> let s1 = signal [1,2,3,4]
-- >>> let s2 = signal [10,20,30,40]
-- >>> let s3 = signal [100,200,300]
-- >>> zipxSY $ vector [s1,s2,s3]
-- {<1,10,100>,<2,20,200>,<3,30,300>}
zipxSY :: Vector (Signal a) -> Signal (Vector a)
zipxSY :: Vector (Signal a) -> Signal (Vector a)
zipxSY = (Signal (Vector a) -> Signal (Vector a) -> Signal (Vector a))
-> Vector (Signal (Vector a)) -> Signal (Vector a)
forall a. (a -> a -> a) -> Vector a -> a
reduceV ((Vector a -> Vector a -> Vector a)
-> Signal (Vector a) -> Signal (Vector a) -> Signal (Vector a)
forall a b c. (a -> b -> c) -> Signal a -> Signal b -> Signal c
zipWithSY Vector a -> Vector a -> Vector a
forall a. Vector a -> Vector a -> Vector a
(<+>)) (Vector (Signal (Vector a)) -> Signal (Vector a))
-> (Vector (Signal a) -> Vector (Signal (Vector a)))
-> Vector (Signal a)
-> Signal (Vector a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Signal a -> Signal (Vector a))
-> Vector (Signal a) -> Vector (Signal (Vector a))
forall a b. (a -> b) -> Vector a -> Vector b
mapV ((a -> Vector a) -> Signal a -> Signal (Vector a)
forall a b. (a -> b) -> Signal a -> Signal b
mapSY a -> Vector a
forall a. a -> Vector a
unitV)
  
-- unsafe implementation! 
-- zipxSY :: Vector (Signal a) -> Signal (Vector a)
-- zipxSY NullV            = NullS
-- zipxSY (NullS   :> xss) = zipxSY xss
-- zipxSY ((x:-xs) :> xss) = (x :> (mapV headS xss)) 
--                           :- (zipxSY (xs :> (mapV tailS xss)))

-- | The process 'unzipxSY' \"unzips\" a vector of signals into a
-- signal of vectors.
unzipxSY :: Signal (Vector a) -> Vector (Signal a)
unzipxSY :: Signal (Vector a) -> Vector (Signal a)
unzipxSY Signal (Vector a)
NullS            = Vector (Signal a)
forall a. Vector a
NullV
unzipxSY (Vector a
NullV   :- Signal (Vector a)
vss) = Signal (Vector a) -> Vector (Signal a)
forall a. Signal (Vector a) -> Vector (Signal a)
unzipxSY Signal (Vector a)
vss
unzipxSY ((a
v:>Vector a
vs) :- Signal (Vector a)
vss) = (a
v a -> Signal a -> Signal a
forall a. a -> Signal a -> Signal a
:- ((Vector a -> a) -> Signal (Vector a) -> Signal a
forall a b. (a -> b) -> Signal a -> Signal b
mapSY Vector a -> a
forall a. Vector a -> a
headV Signal (Vector a)
vss)) 
                            Signal a -> Vector (Signal a) -> Vector (Signal a)
forall a. a -> Vector a -> Vector a
:> (Signal (Vector a) -> Vector (Signal a)
forall a. Signal (Vector a) -> Vector (Signal a)
unzipxSY (Vector a
vs Vector a -> Signal (Vector a) -> Signal (Vector a)
forall a. a -> Signal a -> Signal a
:- ((Vector a -> Vector a) -> Signal (Vector a) -> Signal (Vector a)
forall a b. (a -> b) -> Signal a -> Signal b
mapSY Vector a -> Vector a
forall a. Vector a -> Vector a
tailV Signal (Vector a)
vss)))

-- | The process 'fstSY' selects always the first value from a signal
-- of pairs.
fstSY :: Signal (a,b) -> Signal a
fstSY :: Signal (a, b) -> Signal a
fstSY = ((a, b) -> a) -> Signal (a, b) -> Signal a
forall a b. (a -> b) -> Signal a -> Signal b
mapSY (a, b) -> a
forall a b. (a, b) -> a
fst 

-- | The process 'sndSY' selects always the second value from a signal
-- of pairs.
sndSY :: Signal (a,b) -> Signal b
sndSY :: Signal (a, b) -> Signal b
sndSY = ((a, b) -> b) -> Signal (a, b) -> Signal b
forall a b. (a -> b) -> Signal a -> Signal b
mapSY (a, b) -> b
forall a b. (a, b) -> b
snd