-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Flexible wire arrows for FRP
--   
--   Efficient and flexible wire arrows for functional reactive programming
--   and other forms of locally stateful programming.
@package netwire
@version 4.0.7


-- | Timed maps for efficient cleanups in the context wires.
module Control.Wire.TimedMap

-- | A timed map is a map with an additional index based on time.
data TimedMap t k a

-- | Like <a>lookup</a>, but with a default value, if the key is not in the
--   map.
findWithDefault :: Ord k => (a, t) -> k -> TimedMap t k a -> (a, t)

-- | Look up the given key in the timed map.
lookup :: Ord k => k -> TimedMap t k a -> Maybe (a, t)

-- | Empty timed map.
empty :: TimedMap t k a

-- | Insert into the timed map.
insert :: (Ord k, Ord t) => t -> k -> a -> TimedMap t k a -> TimedMap t k a

-- | Remove all elements older than the given time.
cleanup :: (Ord k, Ord t) => t -> TimedMap t k a -> TimedMap t k a

-- | Remove all but the given number of latest elements.
cut :: (Ord k, Ord t) => Int -> TimedMap t k a -> TimedMap t k a

-- | Deletes the given key from the timed map.
delete :: (Ord k, Ord t) => k -> TimedMap t k a -> TimedMap t k a
instance Typeable3 TimedMap
instance (Data t, Data k, Data a, Ord t, Ord k) => Data (TimedMap t k a)
instance (Show t, Show k, Show a) => Show (TimedMap t k a)


-- | This is the core module implementing the <a>Wire</a> type.
module Control.Wire.Wire

-- | A wire is a signal function from an input value of type <tt>a</tt>
--   that either <i>produces</i> an output value of type <tt>b</tt> or
--   <i>inhibits</i> with a value of type <tt>e</tt>. The underlying monad
--   is <tt>m</tt>.
data Wire e m a b
WGen :: (Time -> a -> m (Either e b, Wire e m a b)) -> Wire e m a b
WPure :: (Time -> a -> (Either e b, Wire e m a b)) -> Wire e m a b

-- | Time.
type Time = Double

-- | Construct a pure stateless wire from the given function.
mkFix :: (Time -> a -> Either e b) -> Wire e m a b

-- | Construct a stateless effectful wire from the given function.
mkFixM :: Monad m => (Time -> a -> m (Either e b)) -> Wire e m a b

-- | Construct an effectful wire from the given function.
mkGen :: (Time -> a -> m (Either e b, Wire e m a b)) -> Wire e m a b

-- | Construct a pure wire from the given function.
mkPure :: (Time -> a -> (Either e b, Wire e m a b)) -> Wire e m a b

-- | Construct a pure wire from the given local state transision function.
mkState :: s -> (Time -> (a, s) -> (Either e b, s)) -> Wire e m a b

-- | Construct a monadic wire from the given local state transision
--   function.
mkStateM :: Monad m => s -> (Time -> (a, s) -> m (Either e b, s)) -> Wire e m a b

-- | Variant of <a>pure</a> without the <a>Monad</a> constraint. Using
--   <a>pure</a> is preferable.
constant :: b -> Wire e m a b

-- | Variant of <a>id</a> without the <a>Monad</a> constraint. Using
--   <a>id</a> is preferable.
--   
--   <ul>
--   <li>Depends: current instant.</li>
--   </ul>
identity :: Wire e m a a

-- | Variant of <a>empty</a> without the <a>Monad</a> constraint. Using
--   <a>empty</a> is preferable.
never :: Monoid e => Wire e m a b

-- | Wire cons. Prepend the given value to the wire's output stream. This
--   function is infixr like (<tt>:</tt>).
--   
--   <ul>
--   <li>Depends: like argument wire after the first instant.</li>
--   <li>Inhibits: like argument wire after the first instant.</li>
--   </ul>
cons :: b -> Wire e m a b -> Wire e m a b

-- | Convenience combinator for the common case of feedback where you
--   ignore the input and produce the feedback value itself with
--   <a>loop</a>.
--   
--   <ul>
--   <li>Depends: like looped argument wire.</li>
--   <li>Inhibits: when argument wire inhibits.</li>
--   </ul>
fixW :: MonadFix m => Wire e m b b -> Wire e m a b

-- | Map the given function over the raw wire output.
mapOutput :: Monad m => (Either e b' -> Either e b) -> Wire e m a b' -> Wire e m a b

-- | Perform an instant of the given wire.
stepWire :: Monad m => Wire e m a b -> Time -> a -> m (Either e b, Wire e m a b)

-- | Perform an instant of the given pure wire.
stepWireP :: Wire e Identity a b -> Time -> a -> (Either e b, Wire e Identity a b)
instance (Monad m, VectorSpace b) => VectorSpace (Wire e m a b)
instance (Monad m, Read b) => Read (Wire e m a b)
instance Monad m => Profunctor (Wire e m)
instance (Monad m, Monoid b) => Monoid (Wire e m a b)
instance (IsString b, Monad m) => IsString (Wire e m a b)
instance (Monad m, Num b) => Num (Wire e m a b)
instance (InnerSpace b, Monad m) => InnerSpace (Wire e m a b)
instance (HasNormal b, Monad m) => HasNormal (Wire e m a b)
instance (HasCross3 b, Monad m) => HasCross3 (Wire e m a b)
instance (HasCross2 b, Monad m) => HasCross2 (Wire e m a b)
instance Monad m => Functor (Wire e m a)
instance (Fractional b, Monad m) => Fractional (Wire e m a b)
instance (Floating b, Monad m) => Floating (Wire e m a b)
instance Monad m => Category (Wire e m)
instance (Monad m, Monoid e) => ArrowZero (Wire e m)
instance (Monad m, Monoid e) => ArrowPlus (Wire e m)
instance MonadFix m => ArrowLoop (Wire e m)
instance Monad m => ArrowChoice (Wire e m)
instance Monad m => Arrow (Wire e m)
instance Monad m => Applicative (Wire e m a)
instance (Monad m, Monoid e) => Alternative (Wire e m a)
instance (AdditiveGroup (Diff b), AffineSpace b, Monad m) => AffineSpace (Wire e m a b)
instance (AdditiveGroup b, Monad m) => AdditiveGroup (Wire e m a b)


-- | Accumulation wires. These are left-scan equivalents of several sorts.
module Control.Wire.Prefab.Accum

-- | The most general accumulator. This wire corresponds to a left scan.
--   
--   <ul>
--   <li>Depends: previous instant.</li>
--   </ul>
accum :: (b -> a -> b) -> b -> Wire e m a b

-- | Like <a>accum</a>, but the accumulation function also receives the
--   current time delta.
--   
--   <ul>
--   <li>Depends: previous instant.</li>
--   </ul>
accumT :: (Time -> b -> a -> b) -> b -> Wire e m a b

-- | Non-delaying variant of <a>accum</a>.
--   
--   <ul>
--   <li>Depends: current instant.</li>
--   </ul>
accum1 :: (b -> a -> b) -> b -> Wire e m a b

-- | Non-delaying variant of <a>accumT</a>.
--   
--   <ul>
--   <li>Depends: current instant.</li>
--   </ul>
accumT1 :: (Time -> b -> a -> b) -> b -> Wire e m a b

-- | Apply the input function continously. Corresponds to <tt>iterate</tt>
--   for lists.
iterateW :: (b -> b) -> b -> Wire e m a b

-- | Like <tt>iterate</tt>, but the accumulation function also receives the
--   current time delta.
iterateWT :: (Time -> b -> b) -> b -> Wire e m a b

-- | Corresponds to <tt>unfoldr</tt> for lists.
--   
--   <ul>
--   <li>Depends: current instant, if the unfolding function is strict in
--   its second argument.</li>
--   </ul>
unfold :: (s -> a -> (b, s)) -> s -> Wire e m a b

-- | Like <a>unfold</a>, but the accumulation function also receives the
--   current time delta.
--   
--   <ul>
--   <li>Depends: current instant, if the given function is strict in its
--   third argument.</li>
--   </ul>
unfoldT :: (Time -> s -> a -> (b, s)) -> s -> Wire e m a b

-- | Counts from the given vector adding the current input for the next
--   instant.
--   
--   <ul>
--   <li>Depends: previous instant.</li>
--   </ul>
countFrom :: AdditiveGroup b => b -> Wire e m b b

-- | Enumerates from the given element.
enumFromW :: Enum b => b -> Wire e m a b

-- | Running <a>Monoid</a> sum.
--   
--   <ul>
--   <li>Depends: previous instant.</li>
--   </ul>
mconcatW :: Monoid b => Wire e m b b


-- | Wires from lists.
module Control.Wire.Prefab.List

-- | Produce the values in the given list cycling forever.
--   
--   <ul>
--   <li>Inhibits: when the argument list is empty.</li>
--   </ul>
cycleW :: (Monad m, Monoid e) => [b] -> Wire e m a b

-- | Produce the values in the given list and then inhibit forever.
--   
--   <ul>
--   <li>Inhibits: when the list is exhausted.</li>
--   </ul>
list :: (Monad m, Monoid e) => [b] -> Wire e m a b


-- | Wires acting as queues.
module Control.Wire.Prefab.Queue

-- | Incoming values are placed in a set, which is discharged element by
--   element. Lower values are served first. Duplicate values are served
--   once.
--   
--   Note: Incorrect usage can lead to congestion.
--   
--   <ul>
--   <li>Complexity: O(n) space wrt bag size.</li>
--   <li>Depends: current instant.</li>
--   <li>Inhibits: when the bag is empty.</li>
--   </ul>
bag :: (Monoid e, Ord b) => Wire e m (Set b) b

-- | First in, first out. The input list is placed on the right end of a
--   queue at every instant, giving earlier elements a higher priority. The
--   queue is discharged item by item from the left.
--   
--   Note: Incorrect usage can lead to congestion.
--   
--   <ul>
--   <li>Complexity: O(n) space wrt queue size.</li>
--   <li>Depends: current instant.</li>
--   <li>Inhibits: when the queue is currently empty.</li>
--   </ul>
fifo :: Monoid e => Wire e m [b] b

-- | Last in, first out. The input list is placed on a stack at every
--   instant, giving earlier elements a higher priority. The stack is
--   discharged item by item from the top.
--   
--   Note: Incorrect usage can lead to congestion.
--   
--   <ul>
--   <li>Complexity: O(n) space wrt stack size.</li>
--   <li>Depends: current instant.</li>
--   <li>Inhibits: when the stack is currently empty.</li>
--   </ul>
lifo :: Monoid e => Wire e m [b] b


-- | Signal sampling wires.
module Control.Wire.Prefab.Sample

-- | Produce the most recent inputs in the given time window. The left
--   input signal is the sample, the right input signal is the time window.
--   
--   <ul>
--   <li>Complexity: O(n), where n the number of samples in the time
--   window.</li>
--   <li>Depends: current instant.</li>
--   </ul>
--   
--   Keep the input signal of the first instant forever.
--   
--   Depends: first instant.
keep :: Wire e m a a

-- | Sample the left signal at discrete intervals given by the right
--   signal.
--   
--   <ul>
--   <li>Depends: instant of the last sample.</li>
--   </ul>
sample :: Wire e m (a, Time) a

-- | Produce up to the given number of most recent inputs.
--   
--   <ul>
--   <li>Complexity: O(n), where n is the given argument.</li>
--   <li>Depends: current instant.</li>
--   </ul>
window :: Int -> Wire e m a (Seq a)

-- | Same as <tt>fmap toList . window</tt>.
windowList :: Monad m => Int -> Wire e m a [a]


-- | Basic wires.
module Control.Wire.Prefab.Simple

-- | Convenience function to add another signal.
--   
--   <ul>
--   <li>Depends: current instant.</li>
--   </ul>
append :: Monad m => Wire e m a b -> Wire e m a (a, b)

-- | One-instant delay.
--   
--   <ul>
--   <li>Depends: previous instant.</li>
--   </ul>
delay :: a -> Wire e m a a

-- | Convenience function to add another signal.
--   
--   <ul>
--   <li>Depends: current instant.</li>
--   </ul>
prepend :: Monad m => Wire e m a b -> Wire e m a (b, a)

-- | Acts like the identity wire, but forces evaluation of the signal to
--   WHNF.
--   
--   <ul>
--   <li>Depends: current instant.</li>
--   </ul>
force :: Wire e m a a

-- | Acts like the identity wire, but forces evaluation of the signal to
--   NF.
--   
--   <ul>
--   <li>Depends: current instant.</li>
--   </ul>
forceNF :: NFData a => Wire e m a a


-- | Time wires.
module Control.Wire.Prefab.Time

-- | Outputs the time delta to the last instant.
--   
--   <ul>
--   <li>Depends: time.</li>
--   </ul>
dtime :: Wire e m a Time

-- | Outputs the current local time passed since the first instant.
--   
--   <ul>
--   <li>Depends: time.</li>
--   </ul>
time :: Wire e m a Time

-- | Outputs the current local time passed since the first instant with the
--   given offset.
--   
--   <ul>
--   <li>Depends: time.</li>
--   </ul>
timeFrom :: Time -> Wire e m a Time


-- | Signal analysis wires.
module Control.Wire.Prefab.Analyze

-- | Calculate the average of the signal over the given number of last
--   samples. If you need an average over all samples ever produced,
--   consider using <a>avgAll</a> instead.
--   
--   <ul>
--   <li>Complexity: O(n) space wrt number of samples.</li>
--   <li>Depends: current instant.</li>
--   </ul>
avg :: (Fractional a, VectorSpace v, Scalar v ~ a) => Int -> Wire e m v v

-- | Same as <a>avg</a>, but with a sampling interval. This can be used to
--   increase the performance, if the input is complicated.
--   
--   <ul>
--   <li>Complexity: O(n) space wrt number of samples.</li>
--   <li>Depends: current instant.</li>
--   </ul>
avgInt :: (Fractional a, VectorSpace v, Scalar v ~ a) => Int -> Int -> Wire e m v v

-- | Calculate the average of the input signal over all samples. This is
--   usually not what you want. In most cases the <a>avg</a> wire is
--   preferable.
--   
--   <ul>
--   <li>Depends: current instant.</li>
--   </ul>
avgAll :: (Fractional a, VectorSpace v, Scalar v ~ a) => Wire e m v v

-- | Calculate the average number of instants per second for the last given
--   number of instants. In a continuous game or simulation this
--   corresponds to the average number of frames per second, hence the
--   name.
--   
--   <ul>
--   <li>Complexity: O(n) space wrt number of samples.</li>
--   <li>Depends: time.</li>
--   </ul>
avgFps :: Monad m => Int -> Wire e m a Double

-- | Like <a>avgFps</a>, but sample in discrete intervals only. This can
--   greatly enhance the performance, when you have an inefficient clock
--   source.
--   
--   <ul>
--   <li>Complexity: O(n) space wrt number of samples.</li>
--   <li>Depends: time.</li>
--   </ul>
avgFpsInt :: Monad m => Int -> Int -> Wire e m a Double

-- | High peak.
--   
--   <ul>
--   <li>Depends: current instant.</li>
--   </ul>
highPeak :: Ord b => Wire e m b b

-- | Low peak.
--   
--   <ul>
--   <li>Depends: current instant.</li>
--   </ul>
lowPeak :: Ord b => Wire e m b b

-- | Output the peak with respect to the given comparison function.
--   
--   <ul>
--   <li>Depends: current instant.</li>
--   </ul>
peakBy :: (b -> b -> Ordering) -> Wire e m b b

-- | Collect all distinct inputs ever received together with a count.
--   Elements not appearing in the map have not been observed yet.
--   
--   <ul>
--   <li>Complexity: O(n) space.</li>
--   <li>Depends: current instant.</li>
--   </ul>
collect :: Ord b => Wire e m b (Map b Int)

-- | Outputs the first local time the input was seen.
--   
--   <ul>
--   <li>Complexity: O(n) space, O(log n) time wrt number of samples so
--   far.</li>
--   <li>Depends: current instant, time.</li>
--   </ul>
firstSeen :: Ord a => Wire e m a Time

-- | Outputs the local time the input was previously seen.
--   
--   <ul>
--   <li>Complexity: O(n) space, O(log n) time wrt number of samples so
--   far.</li>
--   <li>Depends: current instant, time.</li>
--   <li>Inhibits: if this is the first time the input is seen.</li>
--   </ul>
lastSeen :: (Monoid e, Ord a) => Wire e m a Time


-- | This module provides the wires for various kinds of moving objects. In
--   particular this includes various calculus wires like integrals and
--   differentials.
module Control.Wire.Prefab.Move

-- | Integral wire. Produces position from velocity in the sense of the
--   given vector space.
--   
--   <ul>
--   <li>Depends: previous instant.</li>
--   </ul>
integral :: VectorSpace b => b -> Wire e m (b, Scalar b) b

-- | Same as <a>integral</a>, but with respect to time.
--   
--   <ul>
--   <li>Depends: previous instant.</li>
--   </ul>
integral_ :: (VectorSpace b, Scalar b ~ Time) => b -> Wire e m b b

-- | Variant of <a>integral</a>, where you can specify a post-update
--   function, which receives the previous position as well as the current
--   (in that order). This is useful for limiting the output (think of
--   robot arms that can't be moved freely).
--   
--   <ul>
--   <li>Depends: current instant if the post-update function is strict in
--   its first argument, previous instant if not.</li>
--   </ul>
integralLim :: VectorSpace b => (w -> b -> b -> b) -> b -> Wire e m ((b, w), Scalar b) b

-- | Same as <a>integralLim</a>, but with respect to time.
--   
--   <ul>
--   <li>Depends: previous instant.</li>
--   </ul>
integralLim_ :: (VectorSpace b, Scalar b ~ Time) => (w -> b -> b -> b) -> b -> Wire e m (b, w) b

-- | Non-delaying variant of <a>integral</a>.
--   
--   <ul>
--   <li>Depends: current instant.</li>
--   </ul>
integral1 :: VectorSpace b => b -> Wire e m (b, Scalar b) b

-- | Non-delaying variant of <a>integral_</a>.
--   
--   <ul>
--   <li>Depends: current instant.</li>
--   </ul>
integral1_ :: (Monad m, VectorSpace b, Scalar b ~ Time) => b -> Wire e m b b

-- | Non-delaying variant of <a>integralLim</a>.
--   
--   <ul>
--   <li>Depends: current instant.</li>
--   </ul>
integralLim1 :: VectorSpace b => (w -> b -> b -> b) -> b -> Wire e m ((b, w), Scalar b) b

-- | Non-delaying variant of <a>integralLim_</a>.
--   
--   <ul>
--   <li>Depends: current instant.</li>
--   </ul>
integralLim1_ :: (VectorSpace b, Scalar b ~ Time) => (w -> b -> b -> b) -> b -> Wire e m (b, w) b

-- | Derivative. Receives <tt>x</tt> and <tt>dt</tt> and calculates the
--   change rate <tt>dx/dt</tt>. Note that <tt>dt</tt> despite its name
--   does not have to be time.
--   
--   The exception handler function is called when <tt>dt</tt> is zero.
--   That function's result is the wire's output for those instants. If you
--   don't want to handle exceptional cases specially, just pass
--   <tt>(^/)</tt> as the handler function.
--   
--   <ul>
--   <li>Depends: current instant.</li>
--   </ul>
derivative :: (Eq dt, Fractional dt, VectorSpace b, Scalar b ~ dt) => (b -> dt -> b) -> b -> Wire e m (b, dt) b

-- | Same as <a>derivative</a>, but with respect to time.
--   
--   <ul>
--   <li>Depends: current instant.</li>
--   </ul>
derivative_ :: (Monad m, VectorSpace b, Scalar b ~ Time) => (b -> Time -> b) -> b -> Wire e m b b

-- | Objects are generalized integrals. They are controlled through
--   velocity and/or acceleration and can be collision-checked as well as
--   instantly teleported.
--   
--   The post-move update function receives the world state and the current
--   object state. It is applied just before the wire produces its output.
--   You can use it to perform collision-checks or to limit the velocity.
--   
--   Note that teleportation doesn't change the velocity.
--   
--   <ul>
--   <li>Depends: current instant.</li>
--   </ul>
object :: (VectorSpace b, Scalar b ~ dt) => (w -> ObjectState b -> ObjectState b) -> ObjectState b -> Wire e m (ObjectDiff b, w, dt) (ObjectState b)

-- | Same as <a>object</a>, but with respect to time.
--   
--   <ul>
--   <li>Depends: current instant.</li>
--   </ul>
object_ :: (Monad m, VectorSpace b, Scalar b ~ Time) => (w -> ObjectState b -> ObjectState b) -> ObjectState b -> Wire e m (ObjectDiff b, w) (ObjectState b)

-- | Object state. This includes the position and velocity.
data ObjectState a
ObjectState :: a -> a -> ObjectState a

-- | Position.
objPosition :: ObjectState a -> a

-- | Velocity.
objVelocity :: ObjectState a -> a

-- | Differential for objects.
data ObjectDiff a

-- | Accelerate (units per second).
Accelerate :: a -> ObjectDiff a

-- | Teleport to the given position instantly (velocity will be unchanged).
Position :: a -> ObjectDiff a

-- | Specify velocity (units per second).
Velocity :: a -> ObjectDiff a
instance Typeable1 ObjectState
instance Typeable1 ObjectDiff
instance Data a => Data (ObjectState a)
instance Eq a => Eq (ObjectState a)
instance Ord a => Ord (ObjectState a)
instance Read a => Read (ObjectState a)
instance Show a => Show (ObjectState a)
instance Data a => Data (ObjectDiff a)
instance Eq a => Eq (ObjectDiff a)
instance Ord a => Ord (ObjectDiff a)
instance Read a => Read (ObjectDiff a)
instance Show a => Show (ObjectDiff a)


-- | Wire combinators to manage sets of wires.
module Control.Wire.Trans.Combine

-- | The argument function turns the input signal into a context. For each
--   context the given base wire evolves individually.
--   
--   Note: Incorrect usage can lead to a memory leak. Consider using
--   <a>contextLimit</a> instead.
--   
--   <ul>
--   <li>Complexity: O(n) space, O(log n) time wrt to number of stored
--   contexts.</li>
--   <li>Depends: current instant.</li>
--   <li>Inhibits: when the context wire inhibits.</li>
--   </ul>
context :: (Monad m, Ord k) => (a -> k) -> Wire e m a b -> Wire e m a b

-- | Same as <a>context</a>, but keeps only the latest given number of
--   contexts.
contextLatest :: (Monad m, Ord k) => (a -> k) -> Int -> Wire e m a b -> Wire e m a b

-- | Same as <a>context</a>, but applies the given cleanup function to the
--   context map at every instant. This can be used to drop older wires.
contextLimit :: (Monad m, Ord k) => (a -> k) -> (forall w. Int -> Time -> TimedMap Time k w -> TimedMap Time k w) -> Wire e m a b -> Wire e m a b

-- | Broadcast the input signal to all of the given wires collecting their
--   results. Each of the given subwires is evolved individually.
--   
--   <ul>
--   <li>Depends: like the most dependent subwire.</li>
--   <li>Inhibits: when any of the subwires inhibits.</li>
--   </ul>
multicast :: (Monad m, Traversable f) => f (Wire e m a b) -> Wire e m a (f b)


-- | Combinators for embedding wires.
module Control.Wire.Trans.Embed

-- | Performs the argument wire with the input time delta. It is stepped
--   often enough to catch up with the main wire. The individual results
--   are combined as given by the fold (second and third argument).
--   
--   <ul>
--   <li>Complexity: O(n) time wrt stepping the subwire, where n is the
--   number of times the subwire is stepped.</li>
--   <li>Depends: like argument wire, if stepped.</li>
--   <li>Inhibits: When the fold results in a <a>Left</a>.</li>
--   </ul>
embed :: Monad m => (a -> Time) -> (Either e c -> Either e b -> Either e c) -> Either e c -> Wire e m a b -> Wire e m a c


-- | Basic wire combinators.
module Control.Wire.Trans.Simple

-- | The wire <tt>ifW p x y</tt> acts like <tt>x</tt>, when the predicate
--   <tt>p</tt> is true, otherwise <tt>y</tt>.
--   
--   <ul>
--   <li>Complexity: like the predicate and the chosen wire.</li>
--   <li>Depends: like the predicate and the chosen wire.</li>
--   <li>Inhibits: when the predicate or the chosen wire inhibits.</li>
--   </ul>
ifW :: (Monad m, Monoid e) => Wire e m a Bool -> Wire e m a b -> Wire e m a b -> Wire e m a b


-- | Switching combinators. Notice that these combinators restart time when
--   switching.
module Control.Wire.Trans.Switch

-- | Behaves like the first wire until it inhibits. Switches to the second
--   wire as soon as the first one inhibits.
--   
--   The <tt><a>andThen</a></tt> operator is right-associative with
--   precedence 1.
--   
--   <ul>
--   <li>Depends: like currently active wire.</li>
--   <li>Inhibits: when switched to second wire and that one inhibits.</li>
--   <li>Time: switching restarts time.</li>
--   </ul>
andThen :: Monad m => Wire e m a b -> Wire e m a b -> Wire e m a b

-- | If the first argument wire produces a wire, switch to it immediately.
--   If not, evolve the current wire. The second argument wire is the
--   initial wire.
--   
--   <ul>
--   <li>Depends: like event wire and the currently active wire.</li>
--   <li>Inhibits: when the currently active wire inhibits.</li>
--   <li>Time: switching restarts time.</li>
--   </ul>
switch :: Monad m => Wire e m a (Wire e m a b) -> Wire e m a b -> Wire e m a b

-- | Whenever the given wire inhibits, a new wire is constructed using the
--   given function.
--   
--   <ul>
--   <li>Depends: like currently active wire.</li>
--   <li>Time: switching restarts time.</li>
--   </ul>
switchBy :: Monad m => (e' -> Wire e' m a b) -> Wire e' m a b -> Wire e m a b

-- | Infix variant of <a>andThen</a>.
--   
--   This operator is right-associative with precedence 1.
(-->) :: Monad m => Wire e m a b -> Wire e m a b -> Wire e m a b


-- | Time-related wire combinators.
module Control.Wire.Trans.Time

-- | Maps the given function over the time deltas for the given wire.
--   
--   <ul>
--   <li>Complexity: like argument wire.</li>
--   <li>Depends: like argument wire.</li>
--   <li>Inhibits: like argument wire.</li>
--   </ul>
mapTime :: Monad m => (Time -> Time) -> Wire e m a b -> Wire e m a b


-- | Types used in Netwire. Most notably this module implements the
--   instances for the various reactive classes.
module Control.Wire.Types

-- | Monoid for the last occurred exception.
type LastException = Last SomeException

-- | Event wires are wires that act like identity wires, but may inhibit
--   depending on whether a certain event has occurred.
type Event e m a = Wire e m a a

-- | <a>WireM</a> equivalent of <a>Event</a>.
type EventM m a = WireM m a a

-- | <a>WireP</a> equivalent of <a>Event</a>.
type EventP a = WireP a a

-- | Monadic wires using <a>LastException</a> as the inhibition monoid.
type WireM = Wire LastException

-- | Pure wires using <a>LastException</a> as the inhibition monoid.
type WireP = WireM Identity

-- | Type-restricted identity wire. This is useful to specify the type of a
--   signal.
--   
--   <ul>
--   <li>Depends: current instant.</li>
--   </ul>
as :: Monad m => Proxy a -> Wire e m a a

-- | Utility to specify the input type of a wire. The argument is ignored.
--   For types with defaulting you might prefer <a>inLike</a>.
--   
--   <pre>
--   inAs (Proxy :: Proxy Double) highPeak
--   </pre>
inAs :: Proxy a -> w a b -> w a b

-- | Utility to specify the input type of a wire. The first argument is
--   ignored. This is useful to make use of defaulting or when writing a
--   dummy value is actually shorter.
--   
--   <pre>
--   inLike (0 :: Double) highPeak
--   </pre>
inLike :: a -> w a b -> w a b

-- | Type-restricted identity wire. This is useful to specify the type of a
--   signal. The argument is ignored.
--   
--   <ul>
--   <li>Depends: current instant.</li>
--   </ul>
like :: Monad m => a -> Wire e m a a

-- | Utility to specify the output type of a wire. The argument is ignored.
--   For types with defaulting you might prefer <a>outLike</a>.
--   
--   <pre>
--   outAs (Proxy :: Proxy Double) noiseM
--   </pre>
outAs :: Proxy b -> w a b -> w a b

-- | Utility to specify the output type of a wire. The first argument is
--   ignored. This is useful to make use of defaulting or when writing a
--   dummy value is actually shorter.
--   
--   <pre>
--   outLike (0 :: Double) noiseM
--   </pre>
outLike :: b -> w a b -> w a b

-- | <a>Double</a> proxy for use with <a>inAs</a> or <a>outAs</a>.
pDouble :: Proxy Double

-- | <a>Float</a> proxy for use with <a>inAs</a> or <a>outAs</a>.
pFloat :: Proxy Float

-- | <a>Int</a> proxy for use with <a>inAs</a> or <a>outAs</a>.
pInt :: Proxy Int

-- | <a>Integer</a> proxy for use with <a>inAs</a> or <a>outAs</a>.
pInteger :: Proxy Integer

-- | <a>String</a> proxy for use with <a>inAs</a> or <a>outAs</a>.
pString :: Proxy String


-- | Effectful wires.
module Control.Wire.Prefab.Effect

-- | Perform the input monadic action in a wire.
--   
--   <ul>
--   <li>Depends: current instant.</li>
--   </ul>
perform :: Monad m => Wire e m (m b) b

-- | Variant of <a>executeWith</a> for the <a>LastException</a> inhibition
--   monoid.
--   
--   <ul>
--   <li>Depends: current instant.</li>
--   <li>Inhibits: when the action throws an exception.</li>
--   </ul>
execute :: MonadBaseControl IO m => Wire LastException m (m a) a

-- | Variant of <a>executeWith_</a> for the <a>LastException</a> inhibition
--   monoid.
--   
--   <ul>
--   <li>Depends: current instant, if the given function is strict.</li>
--   <li>Inhibits: when the action throws an exception.</li>
--   </ul>
execute_ :: MonadBaseControl IO m => (a -> m b) -> Wire LastException m a b

-- | Perform the input monadic action at every instant.
--   
--   <ul>
--   <li>Depends: current instant.</li>
--   <li>Inhibits: when the action throws an exception.</li>
--   </ul>
executeWith :: MonadBaseControl IO m => (SomeException -> e) -> Wire e m (m a) a

-- | Perform the given monadic action at every instant.
--   
--   <ul>
--   <li>Depends: current instant, if the given function is strict.</li>
--   <li>Inhibits: when the action throws an exception.</li>
--   </ul>
executeWith_ :: MonadBaseControl IO m => (SomeException -> e) -> (a -> m b) -> Wire e m a b

-- | Branch according to the unterlying <a>MonadPlus</a> instance. Note
--   that this wire branches at every instant.
--   
--   <ul>
--   <li>Depends: current instant.</li>
--   </ul>
branch :: MonadPlus m => Wire e m [a] a

-- | Quits the current branch using <a>mzero</a>.
quit :: MonadPlus m => Wire e m a b

-- | Acts like identity in the first instant, then quits the current branch
--   using <a>mzero</a>.
--   
--   <ul>
--   <li>Depends: first instant.</li>
--   </ul>
quitWith :: MonadPlus m => Wire e m a a


-- | Event-related wire combinators.
module Control.Wire.Trans.Event

-- | Try both wires combining their results with the given functions.
--   
--   <ul>
--   <li>Like argument wires.</li>
--   <li>Inhibits: when both wires inhibit.</li>
--   </ul>
eitherE :: (Monad m, Monoid e) => (b1 -> b) -> (b2 -> b) -> (b1 -> b2 -> b) -> Wire e m a b1 -> Wire e m a b2 -> Wire e m a b

-- | Semigroup version of <a>eitherE</a>.
(<||>) :: (Monad m, Monoid e, Semigroup b) => Wire e m a b -> Wire e m a b -> Wire e m a b

-- | Hold the latest event. Produces the last produced value starting with
--   the given one.
--   
--   <ul>
--   <li>Depends: like argument wire.</li>
--   </ul>
hold :: Monad m => b -> Wire e m a b -> Wire e m a b

-- | Hold the event. Once the argument wire produces the produced value is
--   held until the argument wire produces again.
--   
--   <ul>
--   <li>Depends: like argument wire.</li>
--   <li>Inhibits: until the argument wire produces for the first
--   time.</li>
--   </ul>
hold_ :: Monad m => Wire e m a b -> Wire e m a b

-- | Hold the event for the given amount of time. When the argument wire
--   produces, the produced value is kept for the given amount of time. If
--   the wire produces again while another value is kept, the new value
--   takes precedence.
--   
--   <ul>
--   <li>Depends: like argument wire.</li>
--   <li>Inhibits: as described.</li>
--   </ul>
holdFor :: Monad m => Time -> Wire e m a b -> Wire e m a b

-- | Hold the event for the given number of instances. When the argument
--   wire produces, the produced value is kept for the given number of
--   instances. If the wire produces again while another value is kept, the
--   new value takes precedence.
--   
--   <ul>
--   <li>Depends: like argument wire.</li>
--   <li>Inhibits: as described.</li>
--   </ul>
holdForI :: Monad m => Int -> Wire e m a b -> Wire e m a b

-- | If the argument wire inhibits, inhibit with the given exception
--   instead.
--   
--   <ul>
--   <li>Depends: like argument wire.</li>
--   <li>Inhibits: like argument wire.</li>
--   </ul>
(<!>) :: Monad m => Wire e m a b -> e -> Wire e m a b

-- | Prevent a wire from inhibiting. Instead produce a signal wrapped in
--   <a>Maybe</a>.
--   
--   Note: You probably shouldn't use this function.
--   
--   <ul>
--   <li>Depends: like argument wire.</li>
--   </ul>
event :: Monad m => Wire e m a b -> Wire e m a (Maybe b)

-- | Prevent a wire from inhibiting. Instead produce the inhibition value.
--   
--   Note: You probably shouldn't use this function.
--   
--   <ul>
--   <li>Depends: like argument wire.</li>
--   </ul>
exhibit :: Monad m => Wire e m a b -> Wire e m a (Either e b)

-- | Prevent a wire from inhibiting. Instead produce <a>False</a>, if the
--   wire inhibited.
--   
--   Note: You probably shouldn't use this function.
--   
--   <ul>
--   <li>Depends: like argument wire.</li>
--   </ul>
gotEvent :: Monad m => Wire e m a b -> Wire e m a Bool

-- | Act like the identity wire, if the argument wire inhibits. Inhibit, if
--   the argument wire produces.
--   
--   <ul>
--   <li>Depends: like argument wire.</li>
--   <li>Inhibits: when argument wire produces.</li>
--   </ul>
notE :: (Monad m, Monoid e) => Event e m a -> Event e m a


-- | Proxy module to all wire combinator modules.
module Control.Wire.Trans


-- | Wire sessions.
module Control.Wire.Session

-- | Perform an instant of the given wire as part of a wire session.
--   
--   This is a convenience function. You can also construct time deltas
--   yourself entirely circumventing <a>Session</a>. This can be useful, if
--   there is really no need for an effectful monad.
stepSession :: MonadIO m => Wire e m a b -> Session m -> a -> m (Either e b, Wire e m a b, Session m)

-- | Like <a>stepSession</a>, but throws an exception instead of returning
--   an <a>Either</a> value.
stepSession_ :: MonadIO m => WireM m a b -> Session m -> a -> m (b, WireM m a b, Session m)

-- | Like <a>stepSession</a>, but for pure wires.
stepSessionP :: Monad m => Wire e Identity a b -> Session m -> a -> m (Either e b, Wire e Identity a b, Session m)

-- | Like <a>stepSessionP</a>, but throws an exception instead of returning
--   an <a>Either</a> value.
stepSessionP_ :: MonadIO m => WireP a b -> Session m -> a -> m (b, WireP a b, Session m)

-- | Runs the given wire continuously and prints its result to stderr. Runs
--   forever until an exception is raised.
--   
--   The <i>printing interval</i> sets the instants/printing ratio. The
--   higher this value, the less often the output is printed. Examples:
--   1000 means to print at every 1000-th instant, 1 means to print at
--   every instant.
testWire :: (MonadIO m, Show e) => Int -> Int -> m a -> Session m -> Wire e m a String -> m b

-- | Like <a>testWire</a>, but for pure wires.
testWireP :: (MonadIO m, Show e) => Int -> Int -> m a -> Session m -> Wire e Identity a String -> m b

-- | <tt>testPrint n int mx</tt> prints a formatted version of <tt>mx</tt>
--   to stderr, if <tt>n</tt> is zero. It returns <tt>mod (succ n)
--   int</tt>. Requires <tt>n &gt;= 0</tt> to work properly.
--   
--   This function is used to implement the <i>printing interval</i> used
--   in <a>testWire</a> and <tt>testWireM</tt>.
testPrint :: Show e => Int -> Int -> Either e String -> IO Int

-- | A session value contains time-related information.
newtype Session m
Session :: m (Time, Session m) -> Session m
sessionUpdate :: Session m -> m (Time, Session m)

-- | Construct a generic session from the given initial session value and
--   the update function. You can use this function to implement your own
--   clock.
--   
--   If you just want to use real time, you may want to use
--   <a>clockSession</a>.
genSession :: Monad m => a -> (a -> m (Time, a)) -> Session m

-- | Construct a session using real time. This session type uses
--   <a>getCurrentTime</a>. If you have a faster time source, you may want
--   to use <a>genSession</a> instead and construct your own clock.
clockSession :: MonadIO m => Session m

-- | Construct a simple counter session. The time delta is the given
--   argument at every instant.
counterSession :: Monad m => Time -> Session m

-- | Construct a frozen session. Same as <tt><a>counterSession</a> 0</tt>.
frozenSession :: Monad m => Session m


-- | Various type classes.
module Control.Wire.Classes

-- | Monads with a random number generator.
class Monad m => MonadRandom m
getRandom :: (MonadRandom m, Random a) => m a
getRandomR :: (MonadRandom m, Random a) => (a, a) -> m a

-- | Class for injectable values. See <a>inject</a>.
class Injectable e f
toSignal :: Injectable e f => f a -> Either e a
instance MonadRandom IO
instance Injectable e (Either e)
instance Monoid e => Injectable e Maybe


-- | Event wires.
module Control.Wire.Prefab.Event

-- | Produce after the given number of instants.
--   
--   <ul>
--   <li>Depends: current instant when producing.</li>
--   <li>Inhibits: until the given number of instants has passed.</li>
--   </ul>
afterI :: Monoid e => Int -> Event e m a

-- | Variant of <a>periodically</a> in number of instants instead of amount
--   of time.
--   
--   <ul>
--   <li>Depends: current instant when producing.</li>
--   <li>Inhibits: between the given intervals.</li>
--   </ul>
eventsI :: Monoid e => [Int] -> Event e m a

-- | Produce for the given number of instants.
--   
--   <ul>
--   <li>Depends: current instant when producing.</li>
--   <li>Inhibits: after the given number of instants has passed.</li>
--   </ul>
forI :: Monoid e => Int -> Event e m a

-- | Inhibit once.
--   
--   <ul>
--   <li>Depends: current instant after the first instant.</li>
--   <li>Inhibits: in the first instant.</li>
--   </ul>
notYet :: Monoid e => Event e m a

-- | Produce once.
--   
--   <ul>
--   <li>Depends: current instant in the first instant.</li>
--   <li>Inhibits: after the first instant.</li>
--   </ul>
once :: Monoid e => Event e m a

-- | Produce once periodically with the given number of instants as the
--   interval.
--   
--   <ul>
--   <li>Depends: current instant when producing.</li>
--   <li>Inhibits: between the intervals.</li>
--   </ul>
periodicallyI :: Monoid e => Int -> Event e m a

-- | Produce when the signal has changed and at the first instant.
--   
--   <ul>
--   <li>Depends: current instant.</li>
--   <li>Inhibits: after the first instant when the input has changed.</li>
--   </ul>
changed :: (Eq a, Monoid e) => Event e m a

-- | Inject the input signal. Please keep in mind that in application code
--   it is almost always wrong to use this wire. It should only be used to
--   interact with other frameworks/abstractions, and even then it's
--   probably just a last resort.
--   
--   When you want to write your own wires, consider using <a>mkPure</a> or
--   the various variants of it.
--   
--   <ul>
--   <li>Depends: current instant.</li>
--   <li>Inhibits: depending on input signal (see <a>Injectable</a>).</li>
--   </ul>
inject :: Injectable e f => Wire e m (f b) b

-- | Inhibit until the given predicate holds for the input signal. Then
--   produce forever.
--   
--   <ul>
--   <li>Depends: current instant, if the predicate is strict. Once true,
--   on current instant forever.</li>
--   <li>Inhibits: until the predicate becomes true.</li>
--   </ul>
asSoonAs :: Monoid e => (a -> Bool) -> Event e m a

-- | Produces once whenever the given predicate switches from <a>False</a>
--   to <a>True</a>.
--   
--   <ul>
--   <li>Depends: current instant.</li>
--   <li>Inhibits: when the predicate has not just switched from
--   <a>False</a> to <a>True</a>.</li>
--   </ul>
edge :: Monoid e => (a -> Bool) -> Event e m a

-- | Same as <a>unless</a>.
forbid :: Monoid e => (a -> Bool) -> Event e m a

-- | Same as <a>when</a>.
require :: Monoid e => (a -> Bool) -> Event e m a

-- | Produce when the given predicate on the input signal does not hold.
--   
--   <ul>
--   <li>Depends: current instant if the predicate is strict.</li>
--   <li>Inhibits: When the predicate is true.</li>
--   </ul>
unless :: Monoid e => (a -> Bool) -> Event e m a

-- | Produce until the given predicate on the input signal holds, then
--   inhibit forever.
--   
--   <ul>
--   <li>Depends: current instant, if the predicate is strict.</li>
--   <li>Inhibits: forever as soon as the predicate becomes true.</li>
--   </ul>
until :: Monoid e => (a -> Bool) -> Event e m a

-- | Produce when the given predicate on the input signal holds.
--   
--   <ul>
--   <li>Depends: current instant if the predicate is strict.</li>
--   <li>Inhibits: When the predicate is false.</li>
--   </ul>
when :: Monoid e => (a -> Bool) -> Event e m a

-- | Produce while the given predicate on the input signal holds, then
--   inhibit forever.
--   
--   <ul>
--   <li>Depends: current instant, if the predicate is strict.</li>
--   <li>Inhibits: forever as soon as the predicate becomes false.</li>
--   </ul>
while :: Monoid e => (a -> Bool) -> Event e m a

-- | Produce after the given amount of time.
--   
--   <ul>
--   <li>Depends: current instant when producing, time.</li>
--   <li>Inhibits: until the given amount of time has passed.</li>
--   </ul>
after :: Monoid e => Time -> Event e m a

-- | Produce once periodically. The production periods are given by the
--   argument list. When it's <tt>[1,2,3]</tt> it produces after one
--   second, then after two more seconds and finally after three more
--   seconds. When the list is exhausted, it never produces again.
--   
--   <ul>
--   <li>Depends: current instant when producing, time.</li>
--   <li>Inhibits: between the given intervals.</li>
--   </ul>
events :: Monoid e => [Time] -> Event e m a

-- | Produce for the given amount of time.
--   
--   <ul>
--   <li>Depends: current instant when producing, time.</li>
--   <li>Inhibits: after the given amount of time has passed.</li>
--   </ul>
for :: Monoid e => Time -> Event e m a

-- | Produce once periodically with the given time interval.
--   
--   <ul>
--   <li>Depends: current instant when producing, time.</li>
--   <li>Inhibits: between the intervals.</li>
--   </ul>
periodically :: Monoid e => Time -> Event e m a

-- | Inhibit with the given value. You may want to use a combination of
--   <a>empty</a> and <a>&lt;!&gt;</a> instead.
--   
--   <ul>
--   <li>Inhibits: always.</li>
--   </ul>
inhibit :: e -> Wire e m a b


-- | Various noise generators.
module Control.Wire.Prefab.Noise

-- | Pure noise generator.
noise :: (Random b, RandomGen g) => g -> Wire e m a b

-- | Pure ranged noise generator.
--   
--   <ul>
--   <li>Depends: current instant.</li>
--   </ul>
noiseR :: (Random b, RandomGen g) => g -> Wire e m (b, b) b

-- | Event: Occurs randomly with the given probability.
--   
--   <ul>
--   <li>Inhibits: <tt>wackelkontaktM p</tt> inhibits with probability
--   <tt>1 - p</tt>.</li>
--   </ul>
wackelkontakt :: (Monoid e, RandomGen g) => Double -> g -> Event e m a

-- | Noise generator.
noiseM :: (MonadRandom m, Random b) => Wire e m a b

-- | Ranged noise generator.
--   
--   <ul>
--   <li>Depends: current instant.</li>
--   </ul>
noiseRM :: (MonadRandom m, Random b) => Wire e m (b, b) b

-- | Event: Occurs randomly with the given probability.
--   
--   <ul>
--   <li>Inhibits: <tt>wackelkontaktM p</tt> inhibits with probability
--   <tt>1 - p</tt>.</li>
--   </ul>
wackelkontaktM :: (MonadRandom m, Monoid e) => Double -> Event e m a


-- | Proxy module for the prefab wires.
module Control.Wire.Prefab


-- | Netwire is a library for functional reactive programming, that is for
--   time-varying values. It allows you to express various reactive systems
--   elegantly and concisely by using an embedded domain-specific language.
--   Examples of such systems include
--   
--   <ul>
--   <li>games,</li>
--   <li>network applications with time-varying components,</li>
--   <li>simulations,</li>
--   <li>stateful web applications,</li>
--   <li>widget-based user interfaces.</li>
--   </ul>
--   
--   This library is based on an extension of the automaton arrow. The
--   usage is explained in the following tutorial.
module Control.Wire

-- | Formally, the class <a>Profunctor</a> represents a profunctor from
--   <tt>Hask</tt> -&gt; <tt>Hask</tt>.
--   
--   Intuitively it is a bifunctor where the first argument is
--   contravariant and the second argument is covariant.
--   
--   You can define a <a>Profunctor</a> by either defining <a>dimap</a> or
--   by defining both <a>lmap</a> and <a>rmap</a>.
--   
--   If you supply <a>dimap</a>, you should ensure that:
--   
--   <pre>
--   <a>dimap</a> <a>id</a> <a>id</a> ≡ <a>id</a>
--   </pre>
--   
--   If you supply <a>lmap</a> and <a>rmap</a>, ensure:
--   
--   <pre>
--   <a>lmap</a> <a>id</a> ≡ <a>id</a>
--   <a>rmap</a> <a>id</a> ≡ <a>id</a>
--   </pre>
--   
--   If you supply both, you should also ensure:
--   
--   <pre>
--   <a>dimap</a> f g ≡ <a>lmap</a> f <a>.</a> <a>rmap</a> g
--   </pre>
--   
--   These ensure by parametricity:
--   
--   <pre>
--   <a>dimap</a> (f <a>.</a> g) (h <a>.</a> i) ≡ <a>dimap</a> g h <a>.</a> <a>dimap</a> f i
--   <a>lmap</a> (f <a>.</a> g) ≡ <a>lmap</a> g <a>.</a> <a>lmap</a> f
--   <a>rmap</a> (f <a>.</a> g) ≡ <a>rmap</a> f <a>.</a> <a>rmap</a> g
--   </pre>
class Profunctor (p :: * -> * -> *)
dimap :: Profunctor p => (a -> b) -> (c -> d) -> p b c -> p a d
lmap :: Profunctor p => (a -> b) -> p b c -> p a c
rmap :: Profunctor p => (b -> c) -> p a b -> p a c

-- | Any type that you wish to throw or catch as an exception must be an
--   instance of the <tt>Exception</tt> class. The simplest case is a new
--   exception type directly below the root:
--   
--   <pre>
--   data MyException = ThisException | ThatException
--       deriving (Show, Typeable)
--   
--   instance Exception MyException
--   </pre>
--   
--   The default method definitions in the <tt>Exception</tt> class do what
--   we need in this case. You can now throw and catch
--   <tt>ThisException</tt> and <tt>ThatException</tt> as exceptions:
--   
--   <pre>
--   *Main&gt; throw ThisException `catch` \e -&gt; putStrLn ("Caught " ++ show (e :: MyException))
--   Caught ThisException
--   </pre>
--   
--   In more complicated examples, you may wish to define a whole hierarchy
--   of exceptions:
--   
--   <pre>
--   ---------------------------------------------------------------------
--   -- Make the root exception type for all the exceptions in a compiler
--   
--   data SomeCompilerException = forall e . Exception e =&gt; SomeCompilerException e
--       deriving Typeable
--   
--   instance Show SomeCompilerException where
--       show (SomeCompilerException e) = show e
--   
--   instance Exception SomeCompilerException
--   
--   compilerExceptionToException :: Exception e =&gt; e -&gt; SomeException
--   compilerExceptionToException = toException . SomeCompilerException
--   
--   compilerExceptionFromException :: Exception e =&gt; SomeException -&gt; Maybe e
--   compilerExceptionFromException x = do
--       SomeCompilerException a &lt;- fromException x
--       cast a
--   
--   ---------------------------------------------------------------------
--   -- Make a subhierarchy for exceptions in the frontend of the compiler
--   
--   data SomeFrontendException = forall e . Exception e =&gt; SomeFrontendException e
--       deriving Typeable
--   
--   instance Show SomeFrontendException where
--       show (SomeFrontendException e) = show e
--   
--   instance Exception SomeFrontendException where
--       toException = compilerExceptionToException
--       fromException = compilerExceptionFromException
--   
--   frontendExceptionToException :: Exception e =&gt; e -&gt; SomeException
--   frontendExceptionToException = toException . SomeFrontendException
--   
--   frontendExceptionFromException :: Exception e =&gt; SomeException -&gt; Maybe e
--   frontendExceptionFromException x = do
--       SomeFrontendException a &lt;- fromException x
--       cast a
--   
--   ---------------------------------------------------------------------
--   -- Make an exception type for a particular frontend compiler exception
--   
--   data MismatchedParentheses = MismatchedParentheses
--       deriving (Typeable, Show)
--   
--   instance Exception MismatchedParentheses where
--       toException   = frontendExceptionToException
--       fromException = frontendExceptionFromException
--   </pre>
--   
--   We can now catch a <tt>MismatchedParentheses</tt> exception as
--   <tt>MismatchedParentheses</tt>, <tt>SomeFrontendException</tt> or
--   <tt>SomeCompilerException</tt>, but not other types, e.g.
--   <tt>IOException</tt>:
--   
--   <pre>
--   *Main&gt; throw MismatchedParentheses <tt>catch</tt> e -&gt; putStrLn ("Caught " ++ show (e :: MismatchedParentheses))
--   Caught MismatchedParentheses
--   *Main&gt; throw MismatchedParentheses <tt>catch</tt> e -&gt; putStrLn ("Caught " ++ show (e :: SomeFrontendException))
--   Caught MismatchedParentheses
--   *Main&gt; throw MismatchedParentheses <tt>catch</tt> e -&gt; putStrLn ("Caught " ++ show (e :: SomeCompilerException))
--   Caught MismatchedParentheses
--   *Main&gt; throw MismatchedParentheses <tt>catch</tt> e -&gt; putStrLn ("Caught " ++ show (e :: IOException))
--   *** Exception: MismatchedParentheses
--   </pre>
class (Typeable e, Show e) => Exception e
toException :: Exception e => e -> SomeException
fromException :: Exception e => SomeException -> Maybe e

-- | The <tt>SomeException</tt> type is the root of the exception type
--   hierarchy. When an exception of type <tt>e</tt> is thrown, behind the
--   scenes it is encapsulated in a <tt>SomeException</tt>.
data SomeException :: *
SomeException :: e -> SomeException
