-----------------------------------------------------------------------------
-- |
-- Module  :  ForSyDe.Shallow.MoC.Untimed
-- Copyright   :  (c) ForSyDe Group, KTH 2007-2008
-- License     :  BSD-style (see the file LICENSE)
-- 
-- Maintainer  :  forsyde-dev@ict.kth.se
-- Stability   :  experimental
-- Portability :  portable
--
-- The untimed library defines process constructors and processes for
-- the untimed computational model. A process constructor is a higher
-- order function which together with combinational function(s) and
-- values as arguments constructs a process.
-----------------------------------------------------------------------------
module ForSyDe.Shallow.MoC.Untimed (  
  -- * Combinational process constructors
  -- | Combinational process constructors are used for processes that
  -- do not have a state.
  combU, comb2U, comb2UC,
    mapU,
    -- * Sequential process constructors
    -- | Sequential process constructors are used for processes that
    -- have a state. One of the input parameters is the initial state.
    scanU, mealyU, mooreU, sourceU, sinkU, initU,
    -- * Zipping and unzipping signals
    zipU, zipUs,
    zipWithU, zipWith3U, zipWith4U,
    unzipU
  ) where

import ForSyDe.Shallow.Core

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

combU :: Int -> ([a] -> [b]) -> Signal a -> Signal b
combU :: Int -> ([a] -> [b]) -> Signal a -> Signal b
combU = Int -> ([a] -> [b]) -> Signal a -> Signal b
forall a b. Int -> ([a] -> [b]) -> Signal a -> Signal b
mapU

comb2U :: Int -> Int -> ([a]->[b]->[c]) -> Signal a -> Signal b -> Signal c
comb2U :: Int
-> Int -> ([a] -> [b] -> [c]) -> Signal a -> Signal b -> Signal c
comb2U = Int
-> Int -> ([a] -> [b] -> [c]) -> Signal a -> Signal b -> Signal c
forall a b c.
Int
-> Int -> ([a] -> [b] -> [c]) -> Signal a -> Signal b -> Signal c
zipWithU

comb2UC :: Int -> (a->[b]->[c]) -> Signal a -> Signal b -> Signal c
comb2UC :: Int -> (a -> [b] -> [c]) -> Signal a -> Signal b -> Signal c
comb2UC = Int -> (a -> [b] -> [c]) -> Signal a -> Signal b -> Signal c
forall a b c.
Int -> (a -> [b] -> [c]) -> Signal a -> Signal b -> Signal c
zipWithUC

-- | The first parameter of 'mapU' is a constant integer defining the
-- number of tokens consumed in every evaluation cycle. The second
-- argument is a function on lists of the input type and returning a
-- list of the output type. For instance,
--
-- > r2 = mapU 1 f
-- >   where f :: [Int] -> [Int]
-- >     f [x] = [2*x]
--
-- defines a process r2 which consumes one token in each evaluation
-- cycle and multiplies it by two.
mapU :: Int -> ([a] -> [b]) -> Signal a -> Signal b
mapU :: Int -> ([a] -> [b]) -> Signal a -> Signal b
mapU Int
_ [a] -> [b]
_ Signal a
NullS = Signal b
forall a. Signal a
NullS
mapU Int
c [a] -> [b]
f Signal a
xs
  | Signal a -> Int
forall b. Signal b -> Int
lengthS (Int -> Signal a -> Signal a
forall a. Int -> Signal a -> Signal a
takeS Int
c Signal a
xs) Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
c = Signal b
forall a. Signal a
NullS
  | Bool
otherwise = [b] -> Signal b
forall a. [a] -> Signal a
signal ([a] -> [b]
f (Int -> Signal a -> [a]
forall a. Int -> Signal a -> [a]
takeL Int
c Signal a
xs)) Signal b -> Signal b -> Signal b
forall a. Signal a -> Signal a -> Signal a
+-+ (Int -> ([a] -> [b]) -> Signal a -> Signal b
forall a b. Int -> ([a] -> [b]) -> Signal a -> Signal b
mapU Int
c [a] -> [b]
f (Int -> Signal a -> Signal a
forall a. Int -> Signal a -> Signal a
dropS Int
c Signal a
xs))
      
--mapUC :: Int -> ([a] -> b) -> Signal a -> Signal b
--mapUC _ _ NullS = NullS
--mapUC c f xs | lengthS (takeS c xs) < c = NullS
--     | otherwise 
--     =  signal [(f (takeL c xs))] +-+ (mapUC c f (dropS c xs))

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

-- | 'scanU' has an internal state which is visible at the output. The
-- first argument is a function \'gamma\' which, given the state
-- returns the number of tokens consumed next. The second argument is
-- the next state function and the third is the initial state.
scanU :: (b->Int) -> (b->[a]->b) -> b -> Signal a -> Signal b
scanU :: (b -> Int) -> (b -> [a] -> b) -> b -> Signal a -> Signal b
scanU b -> Int
_     b -> [a] -> b
_ b
_     Signal a
NullS = Signal b
forall a. Signal a
NullS
scanU b -> Int
gamma b -> [a] -> b
g b
state Signal a
xs 
  | [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
as Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
c = b
newstate b -> Signal b -> Signal b
forall a. a -> Signal a -> Signal a
:- (b -> Int) -> (b -> [a] -> b) -> b -> Signal a -> Signal b
forall b a.
(b -> Int) -> (b -> [a] -> b) -> b -> Signal a -> Signal b
scanU b -> Int
gamma b -> [a] -> b
g b
newstate (Int -> Signal a -> Signal a
forall a. Int -> Signal a -> Signal a
dropS Int
c Signal a
xs)
  | Bool
otherwise = Signal b
forall a. Signal a
NullS
  where c :: Int
c    = b -> Int
gamma b
state
        as :: [a]
as   = Int -> Signal a -> [a]
forall a. Int -> Signal a -> [a]
takeL Int
c Signal a
xs
        newstate :: b
newstate = b -> [a] -> b
g b
state [a]
as



-- | The process constructor 'mooreU' creates a state machine of Moore
-- type. In addition to the next state function they also have an
-- output encoding function. The output depends directly on the
-- internal state.
mooreU :: (b->Int) -> (b->[a]->b) -> (b -> [c]) -> b -> Signal a -> Signal c
mooreU :: (b -> Int)
-> (b -> [a] -> b) -> (b -> [c]) -> b -> Signal a -> Signal c
mooreU b -> Int
_ b -> [a] -> b
_ b -> [c]
_ b
_ Signal a
NullS = Signal c
forall a. Signal a
NullS
mooreU b -> Int
gamma b -> [a] -> b
g b -> [c]
f b
state Signal a
xs
    | [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
as Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
c = ([c] -> Signal c
forall a. [a] -> Signal a
signal [c]
bs) Signal c -> Signal c -> Signal c
forall a. Signal a -> Signal a -> Signal a
+-+ (b -> Int)
-> (b -> [a] -> b) -> (b -> [c]) -> b -> Signal a -> Signal c
forall b a c.
(b -> Int)
-> (b -> [a] -> b) -> (b -> [c]) -> b -> Signal a -> Signal c
mooreU b -> Int
gamma b -> [a] -> b
g b -> [c]
f b
newstate (Int -> Signal a -> Signal a
forall a. Int -> Signal a -> Signal a
dropS Int
c Signal a
xs)
    | Bool
otherwise  = Signal c
forall a. Signal a
NullS
    where c :: Int
c    = b -> Int
gamma b
state
          as :: [a]
as   = Int -> Signal a -> [a]
forall a. Int -> Signal a -> [a]
takeL Int
c Signal a
xs
          newstate :: b
newstate = b -> [a] -> b
g b
state [a]
as 
          bs :: [c]
bs   = b -> [c]
f b
state

-- | The process constructor 'mealyU' creates a state machine of Moore
-- type. In addition to the next state function they also have an
-- output encoding function. The output depends directly on the
-- internal state.
mealyU :: (b->Int) -> (b->[a]->b) -> (b -> [a] -> [c]) -> b 
   -> Signal a -> Signal c
mealyU :: (b -> Int)
-> (b -> [a] -> b)
-> (b -> [a] -> [c])
-> b
-> Signal a
-> Signal c
mealyU b -> Int
_ b -> [a] -> b
_ b -> [a] -> [c]
_ b
_ Signal a
NullS = Signal c
forall a. Signal a
NullS
mealyU b -> Int
gamma b -> [a] -> b
g b -> [a] -> [c]
f b
state Signal a
xs
  | [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
as Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
c = ([c] -> Signal c
forall a. [a] -> Signal a
signal [c]
bs) 
                     Signal c -> Signal c -> Signal c
forall a. Signal a -> Signal a -> Signal a
+-+ (b -> Int)
-> (b -> [a] -> b)
-> (b -> [a] -> [c])
-> b
-> Signal a
-> Signal c
forall b a c.
(b -> Int)
-> (b -> [a] -> b)
-> (b -> [a] -> [c])
-> b
-> Signal a
-> Signal c
mealyU b -> Int
gamma b -> [a] -> b
g b -> [a] -> [c]
f b
newstate (Int -> Signal a -> Signal a
forall a. Int -> Signal a -> Signal a
dropS Int
c Signal a
xs)
  | Bool
otherwise  = Signal c
forall a. Signal a
NullS
  where c :: Int
c    = b -> Int
gamma b
state
        as :: [a]
as   = Int -> Signal a -> [a]
forall a. Int -> Signal a -> [a]
takeL Int
c Signal a
xs
        newstate :: b
newstate = b -> [a] -> b
g b
state [a]
as
        bs :: [c]
bs   = b -> [a] -> [c]
f b
state [a]
as


zipU  :: Signal (Int,Int) -> Signal a -> Signal b -> Signal ([a],[b])
zipU :: Signal (Int, Int) -> Signal a -> Signal b -> Signal ([a], [b])
zipU Signal (Int, Int)
NullS Signal a
_ Signal b
_ = Signal ([a], [b])
forall a. Signal a
NullS
zipU Signal (Int, Int)
_ Signal a
NullS Signal b
_ = Signal ([a], [b])
forall a. Signal a
NullS
zipU Signal (Int, Int)
_ Signal a
_ Signal b
NullS = Signal ([a], [b])
forall a. Signal a
NullS
zipU ((Int
c1,Int
c2):-Signal (Int, Int)
cs) Signal a
xs Signal b
ys
  | Signal a -> Int
forall b. Signal b -> Int
lengthS (Int -> Signal a -> Signal a
forall a. Int -> Signal a -> Signal a
takeS Int
c1 Signal a
xs) Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
c1 Bool -> Bool -> Bool
&& Signal b -> Int
forall b. Signal b -> Int
lengthS (Int -> Signal b -> Signal b
forall a. Int -> Signal a -> Signal a
takeS Int
c2 Signal b
ys) Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
c2
  = (Int -> Signal a -> [a]
forall a. Int -> Signal a -> [a]
takeL Int
c1 Signal a
xs,Int -> Signal b -> [b]
forall a. Int -> Signal a -> [a]
takeL Int
c2 Signal b
ys) ([a], [b]) -> Signal ([a], [b]) -> Signal ([a], [b])
forall a. a -> Signal a -> Signal a
:- Signal (Int, Int) -> Signal a -> Signal b -> Signal ([a], [b])
forall a b.
Signal (Int, Int) -> Signal a -> Signal b -> Signal ([a], [b])
zipU Signal (Int, Int)
cs (Int -> Signal a -> Signal a
forall a. Int -> Signal a -> Signal a
dropS Int
c1 Signal a
xs) (Int -> Signal b -> Signal b
forall a. Int -> Signal a -> Signal a
dropS Int
c2 Signal b
ys)
  | Bool
otherwise = Signal ([a], [b])
forall a. Signal a
NullS

zipUs :: Int -> Int ->   Signal a -> Signal b -> Signal ([a],[b])
zipUs :: Int -> Int -> Signal a -> Signal b -> Signal ([a], [b])
zipUs Int
_ Int
_ Signal a
NullS Signal b
_ = Signal ([a], [b])
forall a. Signal a
NullS 
zipUs Int
_ Int
_ Signal a
_ Signal b
NullS = Signal ([a], [b])
forall a. Signal a
NullS 
zipUs Int
c1 Int
c2 Signal a
xs Signal b
ys 
  | Signal a -> Int
forall b. Signal b -> Int
lengthS (Int -> Signal a -> Signal a
forall a. Int -> Signal a -> Signal a
takeS Int
c1 Signal a
xs) Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
c1 Bool -> Bool -> Bool
&& Signal b -> Int
forall b. Signal b -> Int
lengthS (Int -> Signal b -> Signal b
forall a. Int -> Signal a -> Signal a
takeS Int
c2 Signal b
ys) Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
c2
  = (Int -> Signal a -> [a]
forall a. Int -> Signal a -> [a]
takeL Int
c1 Signal a
xs,Int -> Signal b -> [b]
forall a. Int -> Signal a -> [a]
takeL Int
c2 Signal b
ys) 
    ([a], [b]) -> Signal ([a], [b]) -> Signal ([a], [b])
forall a. a -> Signal a -> Signal a
:- Int -> Int -> Signal a -> Signal b -> Signal ([a], [b])
forall a b. Int -> Int -> Signal a -> Signal b -> Signal ([a], [b])
zipUs Int
c1 Int
c2 (Int -> Signal a -> Signal a
forall a. Int -> Signal a -> Signal a
dropS Int
c1 Signal a
xs) (Int -> Signal b -> Signal b
forall a. Int -> Signal a -> Signal a
dropS Int
c2 Signal b
ys)
  | Bool
otherwise = Signal ([a], [b])
forall a. Signal a
NullS

zipWithU :: Int -> Int -> ([a]->[b]->[c]) -> Signal a -> Signal b -> Signal c
zipWithU :: Int
-> Int -> ([a] -> [b] -> [c]) -> Signal a -> Signal b -> Signal c
zipWithU Int
_ Int
_ [a] -> [b] -> [c]
_ Signal a
NullS Signal b
_     = Signal c
forall a. Signal a
NullS
zipWithU Int
_ Int
_ [a] -> [b] -> [c]
_ Signal a
_     Signal b
NullS = Signal c
forall a. Signal a
NullS
zipWithU Int
c1 Int
c2 [a] -> [b] -> [c]
f Signal a
xs Signal b
ys 
  | Signal a -> Int
forall b. Signal b -> Int
lengthS (Int -> Signal a -> Signal a
forall a. Int -> Signal a -> Signal a
takeS Int
c1 Signal a
xs) Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
c1 Bool -> Bool -> Bool
&& Signal b -> Int
forall b. Signal b -> Int
lengthS (Int -> Signal b -> Signal b
forall a. Int -> Signal a -> Signal a
takeS Int
c2 Signal b
ys) Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
c2
  = [c] -> Signal c
forall a. [a] -> Signal a
signal ([a] -> [b] -> [c]
f (Int -> Signal a -> [a]
forall a. Int -> Signal a -> [a]
takeL Int
c1 Signal a
xs) (Int -> Signal b -> [b]
forall a. Int -> Signal a -> [a]
takeL Int
c2 Signal b
ys))
    Signal c -> Signal c -> Signal c
forall a. Signal a -> Signal a -> Signal a
+-+ Int
-> Int -> ([a] -> [b] -> [c]) -> Signal a -> Signal b -> Signal c
forall a b c.
Int
-> Int -> ([a] -> [b] -> [c]) -> Signal a -> Signal b -> Signal c
zipWithU Int
c1 Int
c2 [a] -> [b] -> [c]
f (Int -> Signal a -> Signal a
forall a. Int -> Signal a -> Signal a
dropS Int
c1 Signal a
xs) (Int -> Signal b -> Signal b
forall a. Int -> Signal a -> Signal a
dropS Int
c2 Signal b
ys)
  | Bool
otherwise = Signal c
forall a. Signal a
NullS
     
zipWithUC :: Int -> (a->[b]->[c]) -> Signal a -> Signal b -> Signal c
zipWithUC :: Int -> (a -> [b] -> [c]) -> Signal a -> Signal b -> Signal c
zipWithUC Int
_ a -> [b] -> [c]
_ Signal a
NullS Signal b
_ = Signal c
forall a. Signal a
NullS
zipWithUC Int
_ a -> [b] -> [c]
_ Signal a
_ Signal b
NullS = Signal c
forall a. Signal a
NullS
zipWithUC Int
c1 a -> [b] -> [c]
f Signal a
xs Signal b
ys
  | Signal a -> Int
forall b. Signal b -> Int
lengthS (Int -> Signal a -> Signal a
forall a. Int -> Signal a -> Signal a
takeS Int
1 Signal a
xs) Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
1 Bool -> Bool -> Bool
&& Signal b -> Int
forall b. Signal b -> Int
lengthS (Int -> Signal b -> Signal b
forall a. Int -> Signal a -> Signal a
takeS Int
c1 Signal b
ys) Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
c1
  = [c] -> Signal c
forall a. [a] -> Signal a
signal (a -> [b] -> [c]
f (Signal a -> a
forall a. Signal a -> a
headS Signal a
xs) (Int -> Signal b -> [b]
forall a. Int -> Signal a -> [a]
takeL Int
c1 Signal b
ys))
    Signal c -> Signal c -> Signal c
forall a. Signal a -> Signal a -> Signal a
+-+ Int -> (a -> [b] -> [c]) -> Signal a -> Signal b -> Signal c
forall a b c.
Int -> (a -> [b] -> [c]) -> Signal a -> Signal b -> Signal c
zipWithUC Int
c1 a -> [b] -> [c]
f (Signal a -> Signal a
forall a. Signal a -> Signal a
tailS Signal a
xs) (Int -> Signal b -> Signal b
forall a. Int -> Signal a -> Signal a
dropS Int
c1 Signal b
ys)
  | Bool
otherwise = Signal c
forall a. Signal a
NullS

zipWith3U :: Int -> Int -> Int -> ([a]->[b]->[c]->[d])
          -> Signal a -> Signal b -> Signal c -> Signal d
zipWith3U :: Int
-> Int
-> Int
-> ([a] -> [b] -> [c] -> [d])
-> Signal a
-> Signal b
-> Signal c
-> Signal d
zipWith3U Int
_ Int
_ Int
_ [a] -> [b] -> [c] -> [d]
_ Signal a
NullS Signal b
_ Signal c
_ = Signal d
forall a. Signal a
NullS
zipWith3U Int
_ Int
_ Int
_ [a] -> [b] -> [c] -> [d]
_ Signal a
_ Signal b
NullS Signal c
_ = Signal d
forall a. Signal a
NullS
zipWith3U Int
_ Int
_ Int
_ [a] -> [b] -> [c] -> [d]
_ Signal a
_ Signal b
_ Signal c
NullS = Signal d
forall a. Signal a
NullS
zipWith3U Int
c1 Int
c2 Int
c3 [a] -> [b] -> [c] -> [d]
f Signal a
xs Signal b
ys Signal c
zs
  | Signal a -> Int
forall b. Signal b -> Int
lengthS (Int -> Signal a -> Signal a
forall a. Int -> Signal a -> Signal a
takeS Int
c1 Signal a
xs) Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
c1 Bool -> Bool -> Bool
&& Signal b -> Int
forall b. Signal b -> Int
lengthS (Int -> Signal b -> Signal b
forall a. Int -> Signal a -> Signal a
takeS Int
c2 Signal b
ys) Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
c2 Bool -> Bool -> Bool
&& Signal c -> Int
forall b. Signal b -> Int
lengthS (Int -> Signal c -> Signal c
forall a. Int -> Signal a -> Signal a
takeS Int
c3 Signal c
zs) Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
c3
  = [d] -> Signal d
forall a. [a] -> Signal a
signal ([a] -> [b] -> [c] -> [d]
f (Int -> Signal a -> [a]
forall a. Int -> Signal a -> [a]
takeL Int
c1 Signal a
xs) (Int -> Signal b -> [b]
forall a. Int -> Signal a -> [a]
takeL Int
c2 Signal b
ys) (Int -> Signal c -> [c]
forall a. Int -> Signal a -> [a]
takeL Int
c3 Signal c
zs))
    Signal d -> Signal d -> Signal d
forall a. Signal a -> Signal a -> Signal a
+-+ Int
-> Int
-> Int
-> ([a] -> [b] -> [c] -> [d])
-> Signal a
-> Signal b
-> Signal c
-> Signal d
forall a b c d.
Int
-> Int
-> Int
-> ([a] -> [b] -> [c] -> [d])
-> Signal a
-> Signal b
-> Signal c
-> Signal d
zipWith3U Int
c1 Int
c2 Int
c3 [a] -> [b] -> [c] -> [d]
f (Int -> Signal a -> Signal a
forall a. Int -> Signal a -> Signal a
dropS Int
c1 Signal a
xs) (Int -> Signal b -> Signal b
forall a. Int -> Signal a -> Signal a
dropS Int
c2 Signal b
ys) (Int -> Signal c -> Signal c
forall a. Int -> Signal a -> Signal a
dropS Int
c3 Signal c
zs)
  | Bool
otherwise = Signal d
forall a. Signal a
NullS
     
zipWith4U :: Int -> Int -> Int -> Int -> ([a]->[b]->[c]->[d]->[e])
          -> Signal a -> Signal b -> Signal c -> Signal d -> Signal e
zipWith4U :: Int
-> Int
-> Int
-> Int
-> ([a] -> [b] -> [c] -> [d] -> [e])
-> Signal a
-> Signal b
-> Signal c
-> Signal d
-> Signal e
zipWith4U Int
_ Int
_ Int
_ Int
_ [a] -> [b] -> [c] -> [d] -> [e]
_ Signal a
NullS Signal b
_ Signal c
_ Signal d
_= Signal e
forall a. Signal a
NullS
zipWith4U Int
_ Int
_ Int
_ Int
_ [a] -> [b] -> [c] -> [d] -> [e]
_ Signal a
_ Signal b
NullS Signal c
_ Signal d
_ = Signal e
forall a. Signal a
NullS
zipWith4U Int
_ Int
_ Int
_ Int
_ [a] -> [b] -> [c] -> [d] -> [e]
_ Signal a
_ Signal b
_ Signal c
NullS Signal d
_ = Signal e
forall a. Signal a
NullS
zipWith4U Int
_ Int
_ Int
_ Int
_ [a] -> [b] -> [c] -> [d] -> [e]
_ Signal a
_ Signal b
_ Signal c
_ Signal d
NullS = Signal e
forall a. Signal a
NullS
zipWith4U Int
c1 Int
c2 Int
c3 Int
c4 [a] -> [b] -> [c] -> [d] -> [e]
f Signal a
xs Signal b
ys Signal c
zs Signal d
as
  | Signal a -> Int
forall b. Signal b -> Int
lengthS (Int -> Signal a -> Signal a
forall a. Int -> Signal a -> Signal a
takeS Int
c1 Signal a
xs) Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
c1 Bool -> Bool -> Bool
&& Signal b -> Int
forall b. Signal b -> Int
lengthS (Int -> Signal b -> Signal b
forall a. Int -> Signal a -> Signal a
takeS Int
c2 Signal b
ys) Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
c2 
    Bool -> Bool -> Bool
&& Signal c -> Int
forall b. Signal b -> Int
lengthS (Int -> Signal c -> Signal c
forall a. Int -> Signal a -> Signal a
takeS Int
c3 Signal c
zs) Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
c3 Bool -> Bool -> Bool
&& Signal d -> Int
forall b. Signal b -> Int
lengthS (Int -> Signal d -> Signal d
forall a. Int -> Signal a -> Signal a
takeS Int
c4 Signal d
as) Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
c4
  = [e] -> Signal e
forall a. [a] -> Signal a
signal ([a] -> [b] -> [c] -> [d] -> [e]
f (Int -> Signal a -> [a]
forall a. Int -> Signal a -> [a]
takeL Int
c1 Signal a
xs) (Int -> Signal b -> [b]
forall a. Int -> Signal a -> [a]
takeL Int
c2 Signal b
ys) (Int -> Signal c -> [c]
forall a. Int -> Signal a -> [a]
takeL Int
c3 Signal c
zs) (Int -> Signal d -> [d]
forall a. Int -> Signal a -> [a]
takeL Int
c4 Signal d
as))
    Signal e -> Signal e -> Signal e
forall a. Signal a -> Signal a -> Signal a
+-+ Int
-> Int
-> Int
-> Int
-> ([a] -> [b] -> [c] -> [d] -> [e])
-> Signal a
-> Signal b
-> Signal c
-> Signal d
-> Signal e
forall a b c d e.
Int
-> Int
-> Int
-> Int
-> ([a] -> [b] -> [c] -> [d] -> [e])
-> Signal a
-> Signal b
-> Signal c
-> Signal d
-> Signal e
zipWith4U Int
c1 Int
c2 Int
c3 Int
c4 [a] -> [b] -> [c] -> [d] -> [e]
f (Int -> Signal a -> Signal a
forall a. Int -> Signal a -> Signal a
dropS Int
c1 Signal a
xs) (Int -> Signal b -> Signal b
forall a. Int -> Signal a -> Signal a
dropS Int
c2 Signal b
ys) (Int -> Signal c -> Signal c
forall a. Int -> Signal a -> Signal a
dropS Int
c3 Signal c
zs) (Int -> Signal d -> Signal d
forall a. Int -> Signal a -> Signal a
dropS Int
c4 Signal d
as)
  | Bool
otherwise = Signal e
forall a. Signal a
NullS

unzipU :: Signal ([a],[b]) -> (Signal a,Signal b)
unzipU :: Signal ([a], [b]) -> (Signal a, Signal b)
unzipU Signal ([a], [b])
NullS = (Signal a
forall a. Signal a
NullS,Signal b
forall a. Signal a
NullS)
unzipU (([a]
as,[b]
bs):-Signal ([a], [b])
xs) = ([a] -> Signal a
forall a. [a] -> Signal a
signal [a]
as Signal a -> Signal a -> Signal a
forall a. Signal a -> Signal a -> Signal a
+-+ Signal a
ass, 
                        [b] -> Signal b
forall a. [a] -> Signal a
signal [b]
bs Signal b -> Signal b -> Signal b
forall a. Signal a -> Signal a -> Signal a
+-+ Signal b
bss)
  where (Signal a
ass,Signal b
bss) = Signal ([a], [b]) -> (Signal a, Signal b)
forall a b. Signal ([a], [b]) -> (Signal a, Signal b)
unzipU Signal ([a], [b])
xs

sourceU :: (a->a) -> a -> Signal a
sourceU :: (a -> a) -> a -> Signal a
sourceU a -> a
g a
state = a
newstate a -> Signal a -> Signal a
forall a. a -> Signal a -> Signal a
:- (a -> a) -> a -> Signal a
forall a. (a -> a) -> a -> Signal a
sourceU a -> a
g a
newstate
  where newstate :: a
newstate = a -> a
g a
state

sinkU :: (a->Int) -> (a->a) -> a -> Signal b -> Signal b
sinkU :: (a -> Int) -> (a -> a) -> a -> Signal b -> Signal b
sinkU a -> Int
_ a -> a
_ a
_ Signal b
NullS = Signal b
forall a. Signal a
NullS
sinkU a -> Int
gamma a -> a
g a
state Signal b
xs 
  |  [b] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [b]
as Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
c = (a -> Int) -> (a -> a) -> a -> Signal b -> Signal b
forall a b. (a -> Int) -> (a -> a) -> a -> Signal b -> Signal b
sinkU a -> Int
gamma a -> a
g a
newstate (Int -> Signal b -> Signal b
forall a. Int -> Signal a -> Signal a
dropS Int
c Signal b
xs)
  | Bool
otherwise  = Signal b
forall a. Signal a
NullS
  where as :: [b]
as   = Int -> Signal b -> [b]
forall a. Int -> Signal a -> [a]
takeL Int
c Signal b
xs
        c :: Int
c    = a -> Int
gamma a
state
        newstate :: a
newstate = a -> a
g a
state


-- | 'initU' is used to initialise a signal. Its first argument is
-- prepended to its second argument, a signal.
initU :: [a] -> Signal a -> Signal a
initU :: [a] -> Signal a -> Signal a
initU [a]
initial Signal a
s = ([a] -> Signal a
forall a. [a] -> Signal a
signal [a]
initial) Signal a -> Signal a -> Signal a
forall a. Signal a -> Signal a -> Signal a
+-+ Signal a
s

takeL :: Int -> Signal a -> [a]
takeL :: Int -> Signal a -> [a]
takeL Int
c = Signal a -> [a]
forall a. Signal a -> [a]
fromSignal (Signal a -> [a]) -> (Signal a -> Signal a) -> Signal a -> [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int -> Signal a -> Signal a
forall a. Int -> Signal a -> Signal a
takeS Int
c)