content: \begin{comment}
  \begin{code}
  {-# LANGUAGE DeriveDataTypeable #-}
  {-# LANGUAGE GeneralizedNewtypeDeriving #-}
  {-# LANGUAGE RankNTypes #-}
  {-# LANGUAGE RecordWildCards #-}
  {-# LANGUAGE StandaloneDeriving #-}
  
  module LiveCoding.Debugger where
  
  -- base
  import Control.Concurrent
  import Control.Monad (void)
  import Data.Data
  import Data.IORef
  
  -- transformers
  import Control.Monad.Trans.Class (lift)
  import Control.Monad.Trans.State.Strict
  
  -- syb
  import Data.Generics.Text
  
  -- essence-of-live-coding
  import LiveCoding.LiveProgram
  import LiveCoding.Cell
  
  \end{code}
  \end{comment}
  
  \subsection{Debugging the Live State}
  Having the complete state of the program in one place allows us to inspect and debug it in a central place.
  We might want to interact with the user,
  display aspects of the state
  and possibly even change it in place.
  In short, a debugger is a program that can read and modify,
  as an additional effect,
  the state of an arbitrary live program:
  \begin{code}
  newtype Debugger m = Debugger
    { getDebugger :: forall s .
        Data s => LiveProgram (StateT s m)
    }
  \end{code}
  \begin{comment}
  \begin{code}
  -- Standalone deriving isn't clever enough to handle the existential type
  instance Monad m => Semigroup (Debugger m) where
    debugger1 <> debugger2 = Debugger $ getDebugger debugger1 <> getDebugger debugger2
  
  instance Monad m => Monoid (Debugger m) where
    mempty = Debugger mempty
  
  getC :: Monad m => Cell (StateT s m) a s
  getC = constM get
  
  putC :: Monad m => Cell (StateT s m) s ()
  putC = arrM put
  \end{code}
  \end{comment}
  A simple debugger prints the unmodified state to the console:
  \begin{code}
  gshowDebugger :: Debugger IO
  gshowDebugger = Debugger
    $ liveCell $ arrM $ const $ do
      state <- get
      lift $ putStrLn $ gshow state
  \end{code}
  Thanks to the \mintinline{haskell}{Data} typeclass,
  the state does not need to be an instance of \mintinline{haskell}{Show} for this to work:
  \texttt{syb} offers a generic \mintinline{haskell}{gshow} function.
  A more sophisticated debugger could connect to a GUI and display the state there,
  even offering the user to pause the execution and edit the state live.
  \fxwarning{Should I explain countDebugger? What for?}
  \fxerror{Following a comment on cat theory. Add to appendix?}
  \begin{comment}
  Debuggers are endomorphisms in the Kleisli category of \mintinline{haskell}{IO},
  and thus \mintinline{haskell}{Monoid}s:
  A pair of them can be chained by executing them sequentially,
  and the trivial debugger purely \mintinline{haskell}{return}s the state unchanged.
  \end{comment}
  We can bake a debugger into a live program:
  \begin{code}
  withDebugger
    :: Monad       m
    => LiveProgram m
    -> Debugger    m
    -> LiveProgram m
  \end{code}
  \begin{comment}
  \begin{code}
  withDebugger = (liveCell .) . withDebuggerC . toLiveCell
  
  withDebuggerC
    :: Monad    m
    => Cell     m a b
    -> Debugger m
    -> Cell     m a b
  withDebuggerC (Cell state step) (Debugger (LiveProgram dbgState dbgStep)) = Cell { .. }
    where
      cellState = Debugging { .. }
      cellStep Debugging { .. } a = do
        (b, state') <- step state a
        states <- runStateT (dbgStep dbgState) state'
        return (b, uncurry (flip Debugging) states)
  withDebuggerC noCell debugger = withDebuggerC (toCell noCell) debugger
  \end{code}
  \end{comment}
  Again, let us understand the function through its state type:
  \begin{code}
  data Debugging dbgState state = Debugging
    { state    :: state
    , dbgState :: dbgState
    } deriving (Data, Eq, Show)
  \end{code}
  On every step, the debugger becomes active after the cell steps,
  and is fed the current \mintinline{haskell}{state} of the main program.
  Depending on \mintinline{haskell}{dbgState},
  it may execute some side effects or mutate the \mintinline{haskell}{state},
  or do nothing at all\footnote{%
  This option is important for performance: E.g. for an audio application,
  a side effect on every sample can slow down unbearably.}.
  
  Live programs with debuggers are started just as usual.
  \begin{comment}
  \fxwarning{Automatise this and the next output}
  Inspecting the state of the example \mintinline{haskell}{printSineWait} from Section \ref{sec:control flow context} is daunting, though:
  \begin{verbatim}
  Waiting...
  (Composition ((,) (Composition ((,) (())
  (Composition ((,) (()) (Composition ((,)
  (Composition ((,) (()) (Composition ((,)
  [...]
  \end{verbatim}
  \fxerror{I still have the tuples here!}
  The arrow syntax desugaring introduces a lot of irrelevant overhead such as compositions with the trivial state type \mintinline{haskell}{()},
  hiding the parts of the state we are actually interested in.
  Luckily, it is a simple, albeit lengthy exercise in generic programming to prune all irrelevant parts of the state,
  resulting in a tidy output%\footnote{%
  %Line breaks were added to fit the columns.}
   like:
  \end{comment}
  Let us inspect the state of the example \mintinline{haskell}{printSineWait} from Section \ref{sec:control flow context}.
  It is a simple, albeit lengthy exercise in generic programming to prune all irrelevant parts of the state when printing it,
  resulting in a tidy output like:
  \fxwarning{Automatise this}
  \begin{verbatim}
  Waiting...
  NotThrown: (1.0e-3)
   >>> +(0.0) >>> (0.0)+ >>> (1)
  NotThrown: (2.0e-3)
   >>> +(0.0) >>> (0.0)+ >>> (2)
  [...]
  Waiting...
  NotThrown: (2.0009999999998906)
   >>> +(0.0) >>> (0.0)+ >>> (2001)
  Exception:
   >>> +(3.9478417604357436e-3) >>> (0.0)+
   >>> (2002)
  [...]
  \end{verbatim}
  \begin{comment}
  Exception:
   >>> +(7.895683520871487e-3) >>>
   (3.947841760435744e-6)+
   >>> (2003)
  \end{comment}
  The cell is initialised in a state where the exception hasn't been thrown yet,
  and the \mintinline{haskell}{localTime} is \mintinline{haskell}{1.0e-3} seconds.
  The next line corresponds to the initial state (position and velocity) of the sine generator which will be activated after the exception has been thrown,
  followed by the internal counter of \mintinline{haskell}{printEverySecond}.
  In the next step, local time and counter have progressed.
  Two thousand steps later, the exception is finally thrown,
  and the sine wave starts.
  
  \begin{comment}
  \begin{code}
  newtype CountObserver = CountObserver { observe :: IO Integer }
  
  countDebugger :: IO (Debugger IO, CountObserver)
  countDebugger = do
    countRef <- newIORef 0
    observeVar <- newEmptyMVar
    let debugger = Debugger $ liveCell $ arrM $ const $ lift $ do
          n <- readIORef countRef
          putMVar observeVar n
          yield
          void $ takeMVar observeVar
          writeIORef countRef $ n + 1
        observer = CountObserver $ yield >> readMVar observeVar
    return (debugger, observer)
  
  await :: CountObserver -> Integer -> IO ()
  await CountObserver { .. } nMax = go
   where
    go = do
      n <- observe
      if n > nMax then return () else go
  \end{code}
  \end{comment}
  