content: \begin{comment}
  \begin{code}
  {-# LANGUAGE Arrows #-}
  {-# LANGUAGE BangPatterns #-}
  {-# LANGUAGE DeriveDataTypeable #-}
  {-# LANGUAGE RecordWildCards #-}
  
  module LiveCoding.Cell.Feedback where
  
  -- base
  import Control.Arrow
  import Data.Data
  import Data.Maybe (fromMaybe)
  
  -- essence-of-live-coding
  import LiveCoding.Cell
  \end{code}
  \end{comment}
  
  We would like to have all basic primitives needed to develop standard synchronous signal processing components,
  without touching the \mintinline{haskell}{Cell} constructor anymore.
  One crucial bit is missing to achieve this goal:
  Encapsulating state.
  The most general such construction is the feedback loop:
  \begin{code}
  feedback
    :: (Monad m, Data s)
    =>                s
    -> Cell   m   (a, s) (b, s)
    -> Cell   m    a      b
  \end{code}
  Let us have a look at its internal state:
  \begin{code}
  data Feedback sPrevious sAdditional = Feedback
    { sPrevious   :: sPrevious
    , sAdditional :: sAdditional
    } deriving Data
  \end{code}
  In \mintinline{haskell}{feedback sAdditional cell},
  the \mintinline{haskell}{cell} has state \mintinline{haskell}{sPrevious},
  and to this state we add \mintinline{haskell}{sAdditional}.
  The additional state is received by \mintinline{haskell}{cell} as explicit input,
  and \mintinline{haskell}{feedback} hides it.
  
  Note that \mintinline{haskell}{feedback} and \mintinline{haskell}{loop} are different.
  While \mintinline{haskell}{loop} provides immediate recursion, it doesn't add new state.
  \mintinline{haskell}{feedback} requires an initial state and delays it,
  but in turn it is always safe to use since it does not use \mintinline{haskell}{mfix}.
  
  \fxwarning{Possibly remark on Data instance of s?}
  \begin{comment}
  \begin{code}
  feedback sAdditional (Cell sPrevious step) = Cell { .. }
    where
      cellState = Feedback { .. }
      cellStep Feedback { .. } a = do
        ((!b, !sAdditional'), sPrevious') <- step sPrevious (a, sAdditional)
        return (b, Feedback sPrevious' sAdditional')
  feedback cellState (ArrM f) = Cell { .. }
    where
      cellStep state a = f (a, state)
  \end{code}
  \end{comment}
  It enables us to write delays:
  \begin{code}
  delay :: (Data s, Monad m) => s -> Cell m s s
  delay s = feedback s $ arr swap
    where
      swap (sNew, sOld) = (sOld, sNew)
  \end{code}
  \mintinline{haskell}{feedback} can be used for accumulation of data.
  For example, \mintinline{haskell}{sumC} now becomes:
  \begin{code}
  sumFeedback
    :: (Monad m, Num a, Data a)
    => Cell m a a
  sumFeedback = feedback 0 $ arr
    $ \(a, accum) -> (accum, a + accum)
  \end{code}
  