diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -1,82 +1,4 @@
-# README
+* README
 --------
 
-[![Build Status](https://travis-ci.org/turion/rhine.svg?branch=master)](https://travis-ci.org/turion/rhine)
-
-Rhine is a library for synchronous and asynchronous Functional Reactive Programming (FRP).
-It separates the aspects of clocking, scheduling and resampling
-from each other, and ensures clock-safety on the type level.
-
-Complex reactive programs often process data at different rates.
-For example, games, GUIs and media applications
-may output audio and video signals, or receive
-user input at unpredictable times.
-Coordinating these different rates is a hard problem in general.
-If not enough care is taken, buffer underruns and overflows, space and time leaks,
-accidental synchronisation of independent sub-systems,
-and concurrency issues such as dead-locks may all occur.
-
-Rhine tackles these problems by annotating
-the signal processing components with clocks,
-which hold the information when data will be
-input, processed and output.
-Different components of the signal network
-will become active at different times, or work
-at different rates. If components running under different clocks need to communicate, it
-has to be decided when each component be-
-comes active ("scheduling"), and how data is
-transferred between the different rates ("resampling").
-Rhine separates all these aspects from each
-other, and from the individual signal processing of each subsystem.
-It offers a flexible API to all of them and implements several
-reusable standard solutions. In the places
-where these aspects need to intertwine, typing
-constraints on clocks come into effect, enforcing clock safety.
-
-A typical example, which can be run as `cabal run Demonstration`,
-would be:
-
-```
-  -- | Create a simple message containing the time stamp since program start,
-  --   for each tick of the clock.
-  --   Since 'createMessage' works for arbitrary clocks (and doesn't need further input data),
-  --   it is a 'Behaviour'.
-  --   @td@ is the 'TimeDomain' of any clock used to sample,
-  --   and it needs to be constrained in order for time differences
-  --   to have a 'Show' instance.
-  createMessage
-    :: (Monad m, Show (Diff td))
-    => String
-    -> Behaviour m td String
-  createMessage str
-    =   timeInfoOf sinceStart >-> arr show
-    >-> arr (("Clock " ++ str ++ " has ticked at: ") ++)
-
-  -- | Output a message /every second/ (= every 1000 milliseconds).
-  --   Let us assume we want to assure that 'printEverySecond'
-  --   is only called every second,
-  --   then we constrain its type signature with the clock @Millisecond 1000@.
-  printEverySecond :: Show a => SyncSF IO (Millisecond 1000) a ()
-  printEverySecond = arrMSync print
-
-  -- | Specialise 'createMessage' to a specific clock.
-  ms500 :: SyncSF IO (Millisecond 500) () String
-  ms500 = createMessage "500 MS"
-
-
-  ms1200 :: SyncSF IO (Millisecond 1200) () String
-  ms1200 = createMessage "1200 MS"
-
-  -- | Create messages every 500 ms and every 1200 ms,
-  --   collecting all of them in a list,
-  --   which is output every second.
-  main :: IO ()
-  main = flow $
-    ms500 @@ waitClock **@ concurrently @** ms1200 @@ waitClock
-    >-- collect -@- concurrently -->
-    printEverySecond @@ waitClock
-
-  -- | Uncomment the following for a type error (the clocks don't match):
-
-  -- typeError = ms500 >>> printEverySecond
-```
+This is the main library.
diff --git a/rhine.cabal b/rhine.cabal
--- a/rhine.cabal
+++ b/rhine.cabal
@@ -1,6 +1,6 @@
 name:                rhine
 
-version:             0.2.0.0
+version:             0.3.0.0
 
 synopsis: Functional Reactive Programming with type-level clocks
 
@@ -44,7 +44,7 @@
 source-repository this
   type:     git
   location: git@github.com:turion/rhine.git
-  tag:      v0.2.0.0
+  tag:      v0.3.0.0
 
 
 library
@@ -84,7 +84,7 @@
 
   -- Other library packages from which modules are imported.
   build-depends:       base         >= 4.7   && < 5
-                    ,  dunai        == 0.2.0.*
+                    ,  dunai        == 0.3.0.*
                     ,  transformers >= 0.4   && < 0.6
                     ,  time         >= 1.6   && < 1.7
                     ,  free         >= 4.12  && < 4.13
diff --git a/src/FRP/Rhine/SyncSF.hs b/src/FRP/Rhine/SyncSF.hs
--- a/src/FRP/Rhine/SyncSF.hs
+++ b/src/FRP/Rhine/SyncSF.hs
@@ -30,22 +30,30 @@
 
 -- | A (synchronous) monadic stream function
 --   with the additional side effect of being time-aware,
---   that is, reading the current 'TimeInfo' of the clock 'cl'.
+--   that is, reading the current 'TimeInfo' of the clock @cl@.
 type SyncSF m cl a b = MSF (ReaderT (TimeInfo cl) m) a b
 
--- | A synchronous signal is a |SyncSF| with no input required.
+-- | A synchronous signal is a 'SyncSF' with no input required.
 --   It produces its output on its own.
 type SyncSignal m cl a = SyncSF m cl () a
 
 -- | A (side-effectful) behaviour is a time-aware stream
 --   that doesn't depend on a particular clock.
---   'td' denotes the |TimeDomain|.
+--   @td@ denotes the 'TimeDomain'.
 type Behaviour m td a = forall cl. td ~ TimeDomainOf cl => SyncSignal m cl a
 
 -- | Compatibility to U.S. american spelling.
 type Behavior  m td a = Behaviour m td a
 
+-- | A (side-effectful) behaviour function is a time-aware synchronous stream
+--   function that doesn't depend on a particular clock.
+--   @td denotes the 'TimeDomain'.
+type BehaviourF m td a b = forall cl. td ~ TimeDomainOf cl => SyncSF m cl a b
 
+-- | Compatibility to U.S. american spelling.
+type BehaviorF  m td a b = BehaviourF m td a b
+
+
 -- * Utilities to create 'SyncSF's from simpler data
 
 -- TODO Test in which situations it makes sense not to change cl
@@ -131,8 +139,8 @@
 --   of the input, with initial offset @v0@.
 integralFrom
   :: ( Monad m, VectorSpace v
-     , Groundfield v ~ Diff (TimeDomainOf cl))
-  => v -> SyncSF m cl v v
+     , Groundfield v ~ Diff td)
+  => v -> BehaviorF m td v v
 integralFrom v0 = proc v -> do
   _sinceTick <- timeInfoOf sinceTick -< ()
   sumFrom v0                         -< _sinceTick *^ v
@@ -140,8 +148,8 @@
 -- | Euler integration, with zero initial offset.
 integral
   :: ( Monad m, VectorSpace v
-     , Groundfield v ~ Diff (TimeDomainOf cl))
-  => SyncSF m cl v v
+     , Groundfield v ~ Diff td)
+  => BehaviorF m td v v
 integral = integralFrom zeroVector
 
 
@@ -150,8 +158,8 @@
 --   The input is initialised with @v0@.
 derivativeFrom
   :: ( Monad m, VectorSpace v
-     , Groundfield v ~ Diff (TimeDomainOf cl))
-  => v -> SyncSF m cl v v
+     , Groundfield v ~ Diff td)
+  => v -> BehaviorF m td v v
 derivativeFrom v0 = proc v -> do
   vLast         <- delay v0 -< v
   TimeInfo {..} <- timeInfo -< ()
@@ -160,8 +168,8 @@
 -- | Numerical derivative with input initialised to zero.
 derivative
   :: ( Monad m, VectorSpace v
-     , Groundfield v ~ Diff (TimeDomainOf cl))
-  => SyncSF m cl v v
+     , Groundfield v ~ Diff td)
+  => BehaviorF m td v v
 derivative = derivativeFrom zeroVector
 
 -- | A weighted moving average signal function.
@@ -173,9 +181,9 @@
 --   whereas a weight of 0 outputs the current value.
 weightedAverageFrom
   :: ( Monad m, VectorSpace v
-     , Groundfield v ~ Diff (TimeDomainOf cl))
+     , Groundfield v ~ Diff td)
   => v -- ^ The initial position
-  -> SyncSF m cl (v, Groundfield v) v
+  -> BehaviorF m td (v, Groundfield v) v
 weightedAverageFrom v0 = feedback v0 $ proc ((v, weight), vAvg) -> do
   let
     vAvg' = weight *^ vAvg ^+^ (1 - weight) *^ v
@@ -187,10 +195,10 @@
 averageFrom
   :: ( Monad m, VectorSpace v
      , Floating (Groundfield v)
-     , Groundfield v ~ Diff (TimeDomainOf cl))
+     , Groundfield v ~ Diff td)
   => v -- ^ The initial position
-  -> Diff (TimeDomainOf cl) -- ^ The time scale on which the signal is averaged
-  -> SyncSF m cl v v
+  -> Diff td -- ^ The time scale on which the signal is averaged
+  -> BehaviorF m td v v
 averageFrom v0 t = proc v -> do
   TimeInfo {..} <- timeInfo -< ()
   let
@@ -202,9 +210,9 @@
 average
   :: ( Monad m, VectorSpace v
      , Floating (Groundfield v)
-     , Groundfield v ~ Diff (TimeDomainOf cl))
-  => Diff (TimeDomainOf cl) -- ^ The time scale on which the signal is averaged
-  -> SyncSF m cl v v
+     , Groundfield v ~ Diff td)
+  => Diff td -- ^ The time scale on which the signal is averaged
+  -> BehaviourF m td v v
 average = averageFrom zeroVector
 
 -- | A linearised version of 'averageFrom'.
@@ -213,10 +221,10 @@
 --   than the average time difference between two ticks.
 averageLinFrom
   :: ( Monad m, VectorSpace v
-     , Groundfield v ~ Diff (TimeDomainOf cl))
+     , Groundfield v ~ Diff td)
   => v -- ^ The initial position
-  -> Diff (TimeDomainOf cl) -- ^ The time scale on which the signal is averaged
-  -> SyncSF m cl v v
+  -> Diff td -- ^ The time scale on which the signal is averaged
+  -> BehaviourF m td v v
 averageLinFrom v0 t = proc v -> do
   TimeInfo {..} <- timeInfo -< ()
   let
@@ -226,7 +234,7 @@
 -- | Linearised version of 'average'.
 averageLin
   :: ( Monad m, VectorSpace v
-     , Groundfield v ~ Diff (TimeDomainOf cl))
-  => Diff (TimeDomainOf cl) -- ^ The time scale on which the signal is averaged
-  -> SyncSF m cl v v
+     , Groundfield v ~ Diff td)
+  => Diff td -- ^ The time scale on which the signal is averaged
+  -> BehaviourF m td v v
 averageLin = averageLinFrom zeroVector
diff --git a/src/FRP/Rhine/SyncSF/Except.hs b/src/FRP/Rhine/SyncSF/Except.hs
--- a/src/FRP/Rhine/SyncSF/Except.hs
+++ b/src/FRP/Rhine/SyncSF/Except.hs
@@ -1,4 +1,8 @@
-{-# LANGUAGE Arrows #-}
+{-# LANGUAGE Arrows           #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE RankNTypes       #-}
+{-# LANGUAGE TypeFamilies     #-}
+
 module FRP.Rhine.SyncSF.Except
   ( module FRP.Rhine.SyncSF.Except
   , module X
@@ -22,6 +26,13 @@
 
 type SyncExcept m cl a b e = MSFExcept (ReaderT (TimeInfo cl) m) a b e
 
+type BehaviourFExcept m td a b e
+  = forall cl. td ~ TimeDomainOf cl => SyncExcept m cl a b e
+
+-- | Compatibility to U.S. american spelling.
+type BehaviorFExcept m td a b e = BehaviourFExcept m td a b e
+
+
 -- | Commute the effects of the |ReaderT| and the |ExceptT| monad.
 commuteReaderExcept :: ReaderT r (ExceptT e m) a -> ExceptT e (ReaderT r m) a
 commuteReaderExcept a = ExceptT $ ReaderT $ \r -> runExceptT $ runReaderT a r
@@ -57,3 +68,37 @@
 --   and then throws an exception.
 step :: Monad m => (a -> m (b, e)) -> SyncExcept m cl a b e
 step f = MSFE.step $ lift . f
+
+-- | Remembers and indefinitely outputs the first input value.
+keepFirst :: Monad m => SyncSF m cl a a
+keepFirst = safely $ do
+  a <- try throwS
+  safe $ arr $ const a
+
+
+-- | Throws an exception after the specified time difference,
+--   outputting the remaining time difference.
+timer
+  :: ( Monad m
+     , TimeDomain td
+     , Ord (Diff td)
+     )
+  => Diff td
+  -> BehaviorF (ExceptT () m) td a (Diff td)
+timer diff = proc _ -> do
+  time      <- timeInfoOf absolute -< ()
+  startTime <- keepFirst           -< time
+  let remainingTime = time `diffTime` startTime
+  _         <- throwOn ()          -< remainingTime > diff
+  returnA                          -< remainingTime
+
+-- | Like 'timer', but divides the remaining time by the total time.
+scaledTimer
+  :: ( Monad m
+     , TimeDomain td
+     , Fractional (Diff td)
+     , Ord        (Diff td)
+     )
+  => Diff td
+  -> BehaviorF (ExceptT () m) td a (Diff td)
+scaledTimer diff = timer diff >>> arr (/ diff)
