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

-- | Abstractions for animation
--   
--   Active abstraction for animated things with finite start and
--   end times.
@package active
@version 0.2.0.13

-- | Inspired by the work of Kevin Matlage and Andy Gill (Every
--   Animation Should Have a Beginning, a Middle, and an End, Trends
--   in Functional Programming, 2010.
--   http://ku-fpg.github.io/files/Matlage-10-BeginningMiddleEnd.pdf),
--   this module defines a simple abstraction for working with time-varying
--   values. A value of type Active a is either a constant value
--   of type a, or a time-varying value of type a
--   (i.e. a function from time to a) with specific start
--   and end times. Since active values have start and end times, they can
--   be aligned, sequenced, stretched, or reversed.
--   
--   In a sense, this is sort of like a stripped-down version of functional
--   reactive programming (FRP), without the reactivity.
--   
--   The original motivating use for this library is to support making
--   animations with the diagrams framework
--   (http://projects.haskell.org/diagrams), but the hope is that it
--   may find more general utility.
--   
--   There are two basic ways to create an Active value. The first
--   is to use mkActive to create one directly, by specifying a
--   start and end time and a function of time. More indirectly, one can
--   use the Applicative instance together with the unit interval
--   ui, which takes on values from the unit interval from time 0 to
--   time 1, or interval, which creates an active over an arbitrary
--   interval.
--   
--   For example, to create a value of type Active Double which
--   represents one period of a sine wave starting at time 0 and ending at
--   time 1, we could write
--   
--   
--   mkActive 0 1 (\t -> sin (fromTime t * tau))
--   
--   
--   or
--   
--   
--   (sin . (*tau)) <$> ui
--   
--   
--   pure can also be used to create Active values which
--   are constant and have no start or end time. For example,
--   
--   
--   mod <$> (floor <$> interval 0 100) <*> pure 7
--   
--   
--   cycles repeatedly through the numbers 0-6.
--   
--   Note that the "idiom bracket" notation supported by the SHE
--   preprocessor (http://personal.cis.strath.ac.uk/~conor/pub/she/,
--   http://hackage.haskell.org/package/she) can make for somewhat
--   more readable Applicative code. For example, the above example
--   can be rewritten using SHE as
--   
--   
--   {-# OPTIONS_GHC -F -pgmF she #-}
--   
--   ... (| mod (| floor (interval 0 100) |) ~7 |)
--   
--   
--   There are many functions for transforming and composing active values;
--   see the documentation below for more details.
--   
--   With careful handling, this module should be suitable to generating
--   deep embeddings if Active values.
module Data.Active

-- | An abstract type for representing points in time. Note that
--   literal numeric values may be used as Times, thanks to the
--   the Num and Fractional instances.
data Time n

-- | A convenient wrapper function to convert a numeric value into a time.
toTime :: n -> Time n

-- | A convenient unwrapper function to turn a time into a numeric value.
fromTime :: Time n -> n

-- | An abstract type representing elapsed time between two points
--   in time. Note that durations can be negative. Literal numeric values
--   may be used as Durations thanks to the Num and
--   Fractional instances.
data Duration n

-- | A convenient wrapper function to convert a numeric value into a
--   duration.
toDuration :: n -> Duration n

-- | A convenient unwrapper function to turn a duration into a numeric
--   value.
fromDuration :: Duration n -> n

-- | An Era is a concrete span of time, that is, a pair of times
--   representing the start and end of the era. Eras form a
--   semigroup: the combination of two Eras is the smallest
--   Era which contains both. They do not form a Monoid,
--   since there is no Era which acts as the identity with respect
--   to this combining operation.
--   
--   Era is abstract. To construct Era values, use
--   mkEra; to deconstruct, use start and end.
data Era n

-- | Create an Era by specifying start and end Times.
mkEra :: Time n -> Time n -> Era n

-- | Get the start Time of an Era.
start :: Era n -> Time n

-- | Get the end Time of an Era.
end :: Era n -> Time n

-- | Compute the Duration of an Era.
duration :: Num n => Era n -> Duration n

-- | A Dynamic a can be thought of as an a value that
--   changes over the course of a particular Era. It's envisioned
--   that Dynamic will be mostly an internal implementation detail
--   and that Active will be most commonly used. But you never know
--   what uses people might find for things.
data Dynamic a
Dynamic :: Era Rational -> (Time Rational -> a) -> Dynamic a
[era] :: Dynamic a -> Era Rational
[runDynamic] :: Dynamic a -> Time Rational -> a

-- | Create a Dynamic from a start time, an end time, and a
--   time-varying value.
mkDynamic :: Time Rational -> Time Rational -> (Time Rational -> a) -> Dynamic a

-- | Fold for Dynamic.
onDynamic :: (Time Rational -> Time Rational -> (Time Rational -> a) -> b) -> Dynamic a -> b

-- | Shift a Dynamic value by a certain duration.
shiftDynamic :: Duration Rational -> Dynamic a -> Dynamic a

-- | There are two types of Active values:
--   
--   
--   
- An Active can simply be a Dynamic, that is, a
--   time-varying value with start and end times.
--   
- An Active value can also be a constant: a single value,
--   constant across time, with no start and end times.
--   
--   
--   The addition of constant values enable Monoid and
--   Applicative instances for Active.
data Active a

-- | Create a dynamic Active from a start time, an end time, and a
--   time-varying value.
mkActive :: Time Rational -> Time Rational -> (Time Rational -> a) -> Active a

-- | Create an Active value from a Dynamic.
fromDynamic :: Dynamic a -> Active a

-- | Test whether an Active value is constant.
isConstant :: Active a -> Bool

-- | Test whether an Active value is Dynamic.
isDynamic :: Active a -> Bool

-- | Fold for Actives. Process an 'Active a', given a function to
--   apply if it is a pure (constant) value, and a function to apply if it
--   is a Dynamic.
onActive :: (a -> b) -> (Dynamic a -> b) -> Active a -> b

-- | Modify an Active value using a case analysis to see whether it
--   is constant or dynamic.
modActive :: (a -> b) -> (Dynamic a -> Dynamic b) -> Active a -> Active b

-- | Interpret an Active value as a function from time.
runActive :: Active a -> Time Rational -> a

-- | Get the Era of an Active value (or Nothing if it
--   is a constant/pure value).
activeEra :: Active a -> Maybe (Era Rational)

-- | Set the era of an Active value. Note that this will change a
--   constant Active into a dynamic one which happens to have the
--   same value at all times.
setEra :: Era Rational -> Active a -> Active a

-- | atTime t a is an active value with the same behavior as
--   a, shifted so that it starts at time t. If
--   a is constant it is returned unchanged.
atTime :: Time Rational -> Active a -> Active a

-- | Get the value of an Active a at the beginning of its era.
activeStart :: Active a -> a

-- | Get the value of an Active a at the end of its era.
activeEnd :: Active a -> a

-- | ui represents the unit interval, which takes on the
--   value t at time t, and has as its era
--   [0,1]. It is equivalent to interval 0 1, and
--   can be visualized as follows:
--   
--   
--   On the x-axis is time, and the value that ui takes on is on
--   the y-axis. The shaded portion represents the era. Note that the value
--   of ui (as with any active) is still defined outside its era,
--   and this can make a difference when it is combined with other active
--   values with different eras. Applying a function with fmap
--   affects all values, both inside and outside the era. To manipulate
--   values outside the era specifically, see clamp and trim.
--   
--   To alter the values that ui takes on without altering
--   its era, use its Functor and Applicative instances. For
--   example, (*2) <$> ui varies from 0 to
--   2 over the era [0,1]. To alter the era, you can use
--   stretch or shift.
ui :: Fractional a => Active a

-- | interval a b is an active value starting at time a,
--   ending at time b, and taking the value t at time
--   t.
interval :: Fractional a => Time Rational -> Time Rational -> Active a

-- | stretch s act "stretches" the active act so that it
--   takes s times as long (retaining the same start time).
stretch :: Rational -> Active a -> Active a

-- | stretchTo d stretches an Active so it has
--   duration d. Has no effect if (1) d is non-positive,
--   or (2) the Active value is constant, or (3) the Active
--   value has zero duration. [AJG: conditions (1) and (3) no longer true:
--   to consider changing]
stretchTo :: Duration Rational -> Active a -> Active a

-- | a1 `during` a2 stretches and shifts a1
--   so that it has the same era as a2. Has no effect if either of
--   a1 or a2 are constant.
during :: Active a -> Active a -> Active a

-- | shift d act shifts the start time of act by duration
--   d. Has no effect on constant values.
shift :: Duration Rational -> Active a -> Active a

-- | Reverse an active value so the start of its era gets mapped to the end
--   and vice versa. For example, backwards ui can be
--   visualized as
--   
backwards :: Active a -> Active a

-- | Take a "snapshot" of an active value at a particular time, resulting
--   in a constant value.
snapshot :: Time Rational -> Active a -> Active a

-- | "Clamp" an active value so that it is constant before and after its
--   era. Before the era, clamp a takes on the value of a
--   at the start of the era. Likewise, after the era, clamp a
--   takes on the value of a at the end of the era. clamp
--   has no effect on constant values.
--   
--   For example, clamp ui can be visualized as
--   
--   
--   See also clampBefore and clampAfter, which clamp only
--   before or after the era, respectively.
clamp :: Active a -> Active a

-- | "Clamp" an active value so that it is constant before the start of its
--   era. For example, clampBefore ui can be visualized as
--   
--   
--   See the documentation of clamp for more information.
clampBefore :: Active a -> Active a

-- | "Clamp" an active value so that it is constant after the end of its
--   era. For example, clampBefore ui can be visualized as
--   
--   
--   See the documentation of clamp for more information.
clampAfter :: Active a -> Active a

-- | "Trim" an active value so that it is empty outside its era.
--   trim has no effect on constant values.
--   
--   For example, trim ui can be visualized as
--   
--   
--   Actually, trim ui is not well-typed, since it is not
--   guaranteed that ui's values will be monoidal (and usually
--   they won't be)! But the above image still provides a good intuitive
--   idea of what trim is doing. To make this precise we could
--   consider something like trim (First . Just $ ui).
--   
--   See also trimBefore and trimActive, which trim only
--   before or after the era, respectively.
trim :: Monoid a => Active a -> Active a

-- | "Trim" an active value so that it is empty before the start of
--   its era. For example, trimBefore ui can be visualized
--   as
--   
--   
--   See the documentation of trim for more details.
trimBefore :: Monoid a => Active a -> Active a

-- | "Trim" an active value so that it is empty after the end of its
--   era. For example, trimAfter ui can be visualized as
--   
--   
--   See the documentation of trim for more details.
trimAfter :: Monoid a => Active a -> Active a

-- | a1 `after` a2 produces an active that behaves like
--   a1 but is shifted to start at the end time of a2. If
--   either a1 or a2 are constant, a1 is
--   returned unchanged.
after :: Active a -> Active a -> Active a

-- | Sequence/overlay two Active values: shift the second to start
--   immediately after the first (using after), then compose them
--   (using <>).
(->>) :: Semigroup a => Active a -> Active a -> Active a
infixr 5 ->>

-- | "Splice" two Active values together: shift the second to start
--   immediately after the first (using after), and produce the
--   value which acts like the first up to the common end/start point, then
--   like the second after that. If both are constant, return the first.
(|>>) :: Active a -> Active a -> Active a

-- | Splice together a list of active values using |>>. The
--   list must be nonempty.
movie :: [Active a] -> Active a

-- | Create an Active which takes on each value in the given list
--   in turn during the time [0,1], with each value getting an
--   equal amount of time. In other words, discrete creates a
--   "slide show" that starts at time 0 and ends at time 1. The first
--   element is used prior to time 0, and the last element is used after
--   time 1.
--   
--   It is an error to call discrete on the empty list.
discrete :: [a] -> Active a

-- | simulate r act simulates the Active value
--   act, returning a list of "snapshots" taken at regular
--   intervals from the start time to the end time. The interval used is
--   determined by the rate r, which denotes the "frame rate",
--   that is, the number of snapshots per unit time.
--   
--   If the Active value is constant (and thus has no start or end
--   times), a list of length 1 is returned, containing the constant value.
simulate :: Rational -> Active a -> [a]
instance (Data.Active.Active a1 Data.Type.Equality.~ t) => Control.Lens.Wrapped.Rewrapped (Data.Active.Active a2) t
instance Control.Lens.Wrapped.Wrapped (Data.Active.Active a)
instance GHC.Base.Semigroup a => GHC.Base.Semigroup (Data.Active.Active a)
instance (GHC.Base.Monoid a, GHC.Base.Semigroup a) => GHC.Base.Monoid (Data.Active.Active a)
instance GHC.Base.Applicative Data.Active.Active
instance Data.Functor.Bind.Class.Apply Data.Active.Active
instance GHC.Base.Functor Data.Active.Active
instance GHC.Base.Functor Data.Active.Dynamic
instance GHC.Classes.Ord n => GHC.Base.Semigroup (Data.Active.Era n)
instance GHC.Show.Show n => GHC.Show.Show (Data.Active.Era n)
instance Data.Functor.Bind.Class.Apply Data.Active.Dynamic
instance GHC.Base.Semigroup a => GHC.Base.Semigroup (Data.Active.Dynamic a)
instance (Data.Active.Duration n1 Data.Type.Equality.~ t) => Control.Lens.Wrapped.Rewrapped (Data.Active.Duration n2) t
instance Control.Lens.Wrapped.Wrapped (Data.Active.Duration n)
instance GHC.Base.Applicative Data.Active.Duration
instance Linear.Vector.Additive Data.Active.Duration
instance GHC.Num.Num n => GHC.Base.Semigroup (Data.Active.Duration n)
instance GHC.Num.Num n => GHC.Base.Monoid (Data.Active.Duration n)
instance GHC.Base.Functor Data.Active.Duration
instance GHC.Real.RealFrac n => GHC.Real.RealFrac (Data.Active.Duration n)
instance GHC.Real.Real n => GHC.Real.Real (Data.Active.Duration n)
instance GHC.Real.Fractional n => GHC.Real.Fractional (Data.Active.Duration n)
instance GHC.Num.Num n => GHC.Num.Num (Data.Active.Duration n)
instance GHC.Enum.Enum n => GHC.Enum.Enum (Data.Active.Duration n)
instance GHC.Read.Read n => GHC.Read.Read (Data.Active.Duration n)
instance GHC.Show.Show n => GHC.Show.Show (Data.Active.Duration n)
instance GHC.Classes.Ord n => GHC.Classes.Ord (Data.Active.Duration n)
instance GHC.Classes.Eq n => GHC.Classes.Eq (Data.Active.Duration n)
instance Linear.Affine.Affine Data.Active.Time
instance (Data.Active.Time n1 Data.Type.Equality.~ t) => Control.Lens.Wrapped.Rewrapped (Data.Active.Time n2) t
instance Control.Lens.Wrapped.Wrapped (Data.Active.Time n)
instance GHC.Base.Functor Data.Active.Time
instance GHC.Real.RealFrac n => GHC.Real.RealFrac (Data.Active.Time n)
instance GHC.Real.Real n => GHC.Real.Real (Data.Active.Time n)
instance GHC.Real.Fractional n => GHC.Real.Fractional (Data.Active.Time n)
instance GHC.Num.Num n => GHC.Num.Num (Data.Active.Time n)
instance GHC.Enum.Enum n => GHC.Enum.Enum (Data.Active.Time n)
instance GHC.Read.Read n => GHC.Read.Read (Data.Active.Time n)
instance GHC.Show.Show n => GHC.Show.Show (Data.Active.Time n)
instance GHC.Classes.Ord n => GHC.Classes.Ord (Data.Active.Time n)
instance GHC.Classes.Eq n => GHC.Classes.Eq (Data.Active.Time n)
