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


-- | Core libraries for diagrams EDSL
--   
--   The core modules underlying diagrams, an embedded domain-specific
--   language for compositional, declarative drawing.
@package diagrams-core
@version 1.2.0.2


-- | Type family for identifying associated vector spaces.
module Diagrams.Core.V

-- | Many sorts of objects have an associated vector space in which they
--   "live". The type function <tt>V</tt> maps from object types to the
--   associated vector space.


-- | A type for <i>points</i> (as distinct from vectors).
module Diagrams.Core.Points

-- | <tt>Point</tt> is a newtype wrapper around vectors used to represent
--   points, so we don't get them mixed up. The distinction between vectors
--   and points is important: translations affect points, but leave vectors
--   unchanged. Points are instances of the <a>AffineSpace</a> class from
--   <a>Data.AffineSpace</a>.
newtype Point v :: * -> *
P :: v -> Point v

-- | The origin of the vector space <tt>v</tt>.
origin :: AdditiveGroup v => Point v

-- | Scale a point by a scalar.
(*.) :: VectorSpace v => Scalar v -> Point v -> Point v

-- | An isomorphism between points and vectors, given a reference point.
--   This is provided for defining new lenses on points.
_relative :: AffineSpace (Point v) => Point v -> Iso' (Point v) v


-- | Types which have an intrinsic notion of a "local origin", <i>i.e.</i>
--   things which are <i>not</i> invariant under translation.
module Diagrams.Core.HasOrigin

-- | Class of types which have an intrinsic notion of a "local origin",
--   i.e. things which are not invariant under translation, and which allow
--   the origin to be moved.
--   
--   One might wonder why not just use <tt>Transformable</tt> instead of
--   having a separate class for <a>HasOrigin</a>; indeed, for types which
--   are instances of both we should have the identity
--   
--   <pre>
--   moveOriginTo (origin .^+ v) === translate (negateV v)
--   </pre>
--   
--   The reason is that some things (e.g. vectors, <tt>Trail</tt>s) are
--   transformable but are translationally invariant, i.e. have no origin.
class VectorSpace (V t) => HasOrigin t
moveOriginTo :: HasOrigin t => Point (V t) -> t -> t

-- | Move the local origin by a relative vector.
moveOriginBy :: HasOrigin t => V t -> t -> t

-- | Translate the object by the translation that sends the origin to the
--   given point. Note that this is dual to <a>moveOriginTo</a>, i.e. we
--   should have
--   
--   <pre>
--   moveTo (origin .^+ v) === moveOriginTo (origin .^- v)
--   </pre>
--   
--   For types which are also <tt>Transformable</tt>, this is essentially
--   the same as <tt>translate</tt>, i.e.
--   
--   <pre>
--   moveTo (origin .^+ v) === translate v
--   </pre>
moveTo :: HasOrigin t => Point (V t) -> t -> t

-- | A flipped variant of <a>moveTo</a>, provided for convenience. Useful
--   when writing a function which takes a point as an argument, such as
--   when using <tt>withName</tt> and friends.
place :: HasOrigin t => t -> Point (V t) -> t
instance HasOrigin a => HasOrigin (Map k a)
instance (HasOrigin a, Ord a) => HasOrigin (Set a)
instance HasOrigin a => HasOrigin [a]
instance (HasOrigin a, HasOrigin b, V a ~ V b) => HasOrigin (a, b)
instance VectorSpace v => HasOrigin (Point v)


-- | <a>Diagrams</a> defines the core library of primitives forming the
--   basis of an embedded domain-specific language for describing and
--   rendering diagrams.
--   
--   The <tt>Transform</tt> module defines generic transformations
--   parameterized by any vector space.
module Diagrams.Core.Transform

-- | <tt>(v1 :-: v2)</tt> is a linear map paired with its inverse.
data (:-:) u v
(:-:) :: (u :-* v) -> (v :-* u) -> :-: u v

-- | Create an invertible linear map from two functions which are assumed
--   to be linear inverses.
(<->) :: (HasLinearMap u, HasLinearMap v) => (u -> v) -> (v -> u) -> (u :-: v)

-- | Invert a linear map.
linv :: (u :-: v) -> (v :-: u)

-- | Apply a linear map to a vector.
lapp :: (VectorSpace v, Scalar u ~ Scalar v, HasLinearMap u) => (u :-: v) -> u -> v

-- | General (affine) transformations, represented by an invertible linear
--   map, its <i>transpose</i>, and a vector representing a translation
--   component.
--   
--   By the <i>transpose</i> of a linear map we mean simply the linear map
--   corresponding to the transpose of the map's matrix representation. For
--   example, any scale is its own transpose, since scales are represented
--   by matrices with zeros everywhere except the diagonal. The transpose
--   of a rotation is the same as its inverse.
--   
--   The reason we need to keep track of transposes is because it turns out
--   that when transforming a shape according to some linear map L, the
--   shape's <i>normal vectors</i> transform according to L's inverse
--   transpose. This is exactly what we need when transforming bounding
--   functions, which are defined in terms of <i>perpendicular</i> (i.e.
--   normal) hyperplanes.
--   
--   For more general, non-invertable transformations, see
--   <tt>Diagrams.Deform</tt> (in <tt>diagrams-lib</tt>).
data Transformation v
Transformation :: (v :-: v) -> (v :-: v) -> v -> Transformation v

-- | Invert a transformation.
inv :: HasLinearMap v => Transformation v -> Transformation v

-- | Get the transpose of a transformation (ignoring the translation
--   component).
transp :: Transformation v -> (v :-: v)

-- | Get the translational component of a transformation.
transl :: Transformation v -> v

-- | Drop the translational component of a transformation, leaving only the
--   linear part.
dropTransl :: AdditiveGroup v => Transformation v -> Transformation v

-- | Apply a transformation to a vector. Note that any translational
--   component of the transformation will not affect the vector, since
--   vectors are invariant under translation.
apply :: HasLinearMap v => Transformation v -> v -> v

-- | Apply a transformation to a point.
papply :: HasLinearMap v => Transformation v -> Point v -> Point v

-- | Create a general affine transformation from an invertible linear
--   transformation and its transpose. The translational component is
--   assumed to be zero.
fromLinear :: AdditiveGroup v => (v :-: v) -> (v :-: v) -> Transformation v

-- | Get the matrix equivalent of the basis of the vector space v as a list
--   of columns.
basis :: HasLinearMap v => [v]

-- | Get the dimension of an object whose vector space is an instance of
--   <tt>HasLinearMap</tt>, e.g. transformations, paths, diagrams, etc.
dimension :: HasLinearMap (V a) => a -> Int

-- | Get the matrix equivalent of the linear transform, (as a list of
--   columns) and the translation vector. This is mostly useful for
--   implementing backends.
onBasis :: HasLinearMap v => Transformation v -> ([v], v)

-- | Convert a vector v to a list of scalars.
listRep :: HasLinearMap v => v -> [Scalar v]

-- | Convert a `Transformation v` to a matrix representation as a list of
--   column vectors which are also lists.
matrixRep :: HasLinearMap v => Transformation v -> [[Scalar v]]

-- | Convert a `Transformation v` to a homogeneous matrix representation.
--   The final list is the translation. The representation leaves off the
--   last row of the matrix as it is always [0,0, ... 1] and this
--   representation is the defacto standard for backends.
matrixHomRep :: HasLinearMap v => Transformation v -> [[Scalar v]]

-- | The determinant of a <a>Transformation</a>.
determinant :: (HasLinearMap v, Num (Scalar v)) => Transformation v -> Scalar v

-- | Compute the "average" amount of scaling performed by a transformation.
--   Satisfies the properties
--   
--   <pre>
--   avgScale (scaling k) == k
--   avgScale (t1 <a></a> t2)  == avgScale t1 * avgScale t2
--   </pre>
avgScale :: (HasLinearMap v, Floating (Scalar v)) => Transformation v -> Scalar v

-- | <a>HasLinearMap</a> is a poor man's class constraint synonym, just to
--   help shorten some of the ridiculously long constraint sets.
class (HasBasis v, HasTrie (Basis v), VectorSpace v) => HasLinearMap v

-- | Type class for things <tt>t</tt> which can be transformed.
class HasLinearMap (V t) => Transformable t
transform :: Transformable t => Transformation (V t) -> t -> t

-- | <tt>TransInv</tt> is a wrapper which makes a transformable type
--   translationally invariant; the translational component of
--   transformations will no longer affect things wrapped in
--   <tt>TransInv</tt>.
newtype TransInv t
TransInv :: t -> TransInv t

-- | Create a translation.
translation :: HasLinearMap v => v -> Transformation v

-- | Translate by a vector.
translate :: (Transformable t, HasLinearMap (V t)) => V t -> t -> t

-- | Create a uniform scaling transformation.
scaling :: (HasLinearMap v, Fractional (Scalar v)) => Scalar v -> Transformation v

-- | Scale uniformly in every dimension by the given scalar.
scale :: (Transformable t, Fractional (Scalar (V t)), Eq (Scalar (V t))) => Scalar (V t) -> t -> t
instance Eq t => Eq (TransInv t)
instance Ord t => Ord (TransInv t)
instance Show t => Show (TransInv t)
instance Semigroup t => Semigroup (TransInv t)
instance Monoid t => Monoid (TransInv t)
instance Transformable t => Transformable (TransInv t)
instance VectorSpace (V t) => HasOrigin (TransInv t)
instance Rewrapped (TransInv t) (TransInv t')
instance Wrapped (TransInv t)
instance Transformable Rational
instance Transformable Double
instance Transformable m => Transformable (Deletable m)
instance HasLinearMap v => Transformable (Point v)
instance Transformable t => Transformable (Map k t)
instance (Transformable t, Ord t) => Transformable (Set t)
instance Transformable t => Transformable [t]
instance (HasBasis (V b), HasTrie (Basis (V b)), Transformable a, Transformable b, V b ~ V a) => Transformable (a -> b)
instance (Transformable a, Transformable b, Transformable c, V a ~ V b, V a ~ V c) => Transformable (a, b, c)
instance (Transformable a, Transformable b, V a ~ V b) => Transformable (a, b)
instance HasLinearMap v => HasOrigin (Transformation v)
instance HasLinearMap v => Transformable (Transformation v)
instance (HasBasis v, HasTrie (Basis v), VectorSpace v) => HasLinearMap v
instance (HasLinearMap v, v ~ V a, Transformable a) => Action (Transformation v) a
instance HasLinearMap v => Monoid (Transformation v)
instance HasLinearMap v => Semigroup (Transformation v)
instance HasLinearMap v => Monoid (v :-: v)
instance HasLinearMap v => Semigroup (v :-: v)


-- | This module defines a type of names which can be used for referring to
--   subdiagrams, and related types.
module Diagrams.Core.Names

-- | Atomic names. <tt>AName</tt> is just an existential wrapper around
--   things which are <a>Typeable</a>, <a>Ord</a> and <a>Show</a>.
data AName
AName :: a -> AName

-- | A (qualified) name is a (possibly empty) sequence of atomic names.
newtype Name
Name :: [AName] -> Name

-- | Class for those types which can be used as names. They must support
--   <a>Typeable</a> (to facilitate extracting them from existential
--   wrappers), <a>Ord</a> (for comparison and efficient storage) and
--   <a>Show</a>.
--   
--   To make an instance of <a>IsName</a>, you need not define any methods,
--   just declare it.
--   
--   WARNING: it is not recommended to use
--   <tt>GeneralizedNewtypeDeriving</tt> in conjunction with
--   <tt>IsName</tt>, since in that case the underlying type and the
--   <tt>newtype</tt> will be considered equivalent when comparing names.
--   For example:
--   
--   <pre>
--   newtype WordN = WordN Int deriving (Show, Ord, Eq, Typeable, IsName)
--   </pre>
--   
--   is unlikely to work as intended, since <tt>(1 :: Int)</tt> and
--   <tt>(WordN 1)</tt> will be considered equal as names. Instead, use
--   
--   <pre>
--   newtype WordN = WordN Int deriving (Show, Ord, Eq, Typeable, IsName)
--   instance IsName WordN
--   </pre>
class (Typeable a, Ord a, Show a) => IsName a where toName = Name . (: []) . AName
toName :: IsName a => a -> Name

-- | Convenient operator for writing qualified names with atomic components
--   of different types. Instead of writing <tt>toName a1 &lt;&gt; toName
--   a2 &lt;&gt; toName a3</tt> you can just write <tt>a1 .&gt; a2 .&gt;
--   a3</tt>.
(.>) :: (IsName a1, IsName a2) => a1 -> a2 -> Name

-- | Instances of <a>Qualifiable</a> are things which can be qualified by
--   prefixing them with a name.
class Qualifiable q
(|>) :: (Qualifiable q, IsName a) => a -> q -> q
instance [overlap ok] Typeable AName
instance [overlap ok] Typeable Name
instance [overlap ok] Eq Name
instance [overlap ok] Ord Name
instance [overlap ok] Semigroup Name
instance [overlap ok] Monoid Name
instance [overlap ok] Qualifiable a => Qualifiable (b -> a)
instance [overlap ok] Qualifiable a => Qualifiable (Map k a)
instance [overlap ok] (Ord a, Qualifiable a) => Qualifiable (Set a)
instance [overlap ok] Qualifiable a => Qualifiable [a]
instance [overlap ok] (Qualifiable a, Qualifiable b, Qualifiable c) => Qualifiable (a, b, c)
instance [overlap ok] (Qualifiable a, Qualifiable b) => Qualifiable (a, b)
instance [overlap ok] Qualifiable a => Qualifiable (TransInv a)
instance [overlap ok] Qualifiable Name
instance [overlap ok] IsName Name
instance [overlap ok] Show Name
instance [overlap ok] Rewrapped Name Name
instance [overlap ok] Wrapped Name
instance [overlap ok] Show AName
instance [overlap ok] Ord AName
instance [overlap ok] Eq AName
instance [overlap ok] IsName AName
instance [overlap ok] (IsName a, IsName b, IsName c) => IsName (a, b, c)
instance [overlap ok] (IsName a, IsName b) => IsName (a, b)
instance [overlap ok] IsName a => IsName [a]
instance [overlap ok] IsName String
instance [overlap ok] IsName Integer
instance [overlap ok] IsName Double
instance [overlap ok] IsName Float
instance [overlap ok] IsName Int
instance [overlap ok] IsName Char
instance [overlap ok] IsName Bool
instance [overlap ok] IsName ()


-- | The <tt>Query</tt> module defines a type for "queries" on diagrams,
--   which are functions from points in a vector space to some monoid.
module Diagrams.Core.Query

-- | A query is a function that maps points in a vector space to values in
--   some monoid. Queries naturally form a monoid, with two queries being
--   combined pointwise.
--   
--   The idea for annotating diagrams with monoidal queries came from the
--   graphics-drawingcombinators package,
--   <a>http://hackage.haskell.org/package/graphics-drawingcombinators</a>.
newtype Query v m
Query :: (Point v -> m) -> Query v m
runQuery :: Query v m -> Point v -> m
instance Functor (Query v)
instance Applicative (Query v)
instance Semigroup m => Semigroup (Query v m)
instance Monoid m => Monoid (Query v m)
instance HasLinearMap v => Transformable (Query v m)
instance VectorSpace v => HasOrigin (Query v m)
instance Rewrapped (Query v m) (Query v' m')
instance Wrapped (Query v m)


-- | A definition of <i>styles</i> for diagrams as extensible,
--   heterogeneous collections of attributes.
module Diagrams.Core.Style

-- | Every attribute must be an instance of <tt>AttributeClass</tt>, which
--   simply guarantees <a>Typeable</a> and <a>Semigroup</a> constraints.
--   The <a>Semigroup</a> instance for an attribute determines how it will
--   combine with other attributes of the same type.
class (Typeable a, Semigroup a) => AttributeClass a

-- | An existential wrapper type to hold attributes. Some attributes are
--   simply inert/static; some are affected by transformations; and some
--   are affected by transformations and can be modified generically.
data Attribute v :: *
Attribute :: a -> Attribute v
TAttribute :: a -> Attribute v
GTAttribute :: a -> Attribute v

-- | Wrap up an attribute.
mkAttr :: AttributeClass a => a -> Attribute v

-- | Wrap up a transformable attribute.
mkTAttr :: (AttributeClass a, Transformable a, V a ~ v) => a -> Attribute v

-- | Wrap up a transformable and generic attribute.
mkGTAttr :: (AttributeClass a, Data a, Transformable a, V a ~ v) => a -> Attribute v

-- | Unwrap an unknown <a>Attribute</a> type, performing a dynamic (but
--   safe) check on the type of the result. If the required type matches
--   the type of the attribute, the attribute value is returned wrapped in
--   <tt>Just</tt>; if the types do not match, <tt>Nothing</tt> is
--   returned.
unwrapAttr :: AttributeClass a => Attribute v -> Maybe a

-- | Apply an attribute to an instance of <a>HasStyle</a> (such as a
--   diagram or a style). If the object already has an attribute of the
--   same type, the new attribute is combined on the left with the existing
--   attribute, according to their semigroup structure.
applyAttr :: (AttributeClass a, HasStyle d) => a -> d -> d

-- | Apply a transformable attribute to an instance of <a>HasStyle</a>
--   (such as a diagram or a style). If the object already has an attribute
--   of the same type, the new attribute is combined on the left with the
--   existing attribute, according to their semigroup structure.
applyTAttr :: (AttributeClass a, Transformable a, V a ~ V d, HasStyle d) => a -> d -> d
applyGTAttr :: (AttributeClass a, Data a, Transformable a, V a ~ V d, HasStyle d) => a -> d -> d

-- | A <tt>Style</tt> is a heterogeneous collection of attributes,
--   containing at most one attribute of any given type.
newtype Style v
Style :: (Map String (Attribute v)) -> Style v

-- | Create a style from a single attribute.
attrToStyle :: AttributeClass a => a -> Style v

-- | Create a style from a single transformable attribute.
tAttrToStyle :: (AttributeClass a, Transformable a, V a ~ v) => a -> Style v

-- | Create a style from a single transformable, generic attribute.
gtAttrToStyle :: (AttributeClass a, Data a, Transformable a, V a ~ v) => a -> Style v

-- | Extract an attribute from a style of a particular type. If the style
--   contains an attribute of the requested type, it will be returned
--   wrapped in <tt>Just</tt>; otherwise, <tt>Nothing</tt> is returned.
getAttr :: AttributeClass a => Style v -> Maybe a

-- | Add a new attribute to a style, or replace the old attribute of the
--   same type if one exists.
setAttr :: AttributeClass a => a -> Style v -> Style v

-- | Attempt to add a new attribute to a style, but if an attribute of the
--   same type already exists, do not replace it.
addAttr :: AttributeClass a => a -> Style v -> Style v

-- | Add a new attribute to a style that does not already contain an
--   attribute of this type, or combine it on the left with an existing
--   attribute.
combineAttr :: AttributeClass a => a -> Style v -> Style v

-- | Map generically over all generic attributes in a style, applying the
--   given function to any values with the given type, even deeply nested
--   ones. Note that only attributes wrapped in <a>GTAttribute</a> are
--   affected.
gmapAttrs :: Typeable a => (a -> a) -> Style v -> Style v

-- | Type class for things which have a style.
class HasStyle a
applyStyle :: HasStyle a => Style (V a) -> a -> a
instance (HasStyle a, Ord a) => HasStyle (Set a)
instance HasStyle a => HasStyle (Map k a)
instance HasStyle b => HasStyle (a -> b)
instance HasStyle a => HasStyle [a]
instance (HasStyle a, HasStyle b, V a ~ V b) => HasStyle (a, b)
instance HasStyle (Style v)
instance Action (Style v) m
instance HasLinearMap v => Transformable (Style v)
instance Monoid (Style v)
instance Semigroup (Style v)
instance Rewrapped (Style v) (Style v')
instance Wrapped (Style v)
instance HasLinearMap v => Transformable (Attribute v)
instance Semigroup (Attribute v)


-- | <tt>diagrams-core</tt> defines the core library of primitives forming
--   the basis of an embedded domain-specific language for describing and
--   rendering diagrams.
--   
--   The <tt>Trace</tt> module defines a data type and type class for
--   "traces", aka functional boundaries, essentially corresponding to
--   embedding a raytracer with each diagram.
module Diagrams.Core.Trace

-- | A newtype wrapper around a list which maintains the invariant that the
--   list is sorted. The constructor is not exported; use the smart
--   constructor <a>mkSortedList</a> (which sorts the given list) instead.
data SortedList a

-- | A smart constructor for the <a>SortedList</a> type, which sorts the
--   input to ensure the <a>SortedList</a> invariant.
mkSortedList :: Ord a => [a] -> SortedList a

-- | Project the (guaranteed sorted) list out of a <a>SortedList</a>
--   wrapper.
getSortedList :: SortedList a -> [a]

-- | Apply a list function to a <a>SortedList</a>. The function need not
--   result in a sorted list; the result will be sorted before being
--   rewrapped as a <a>SortedList</a>.
onSortedList :: Ord b => ([a] -> [b]) -> (SortedList a -> SortedList b)

-- | Apply an <i>order-preserving</i> list function to a <a>SortedList</a>.
--   No sorts or checks are done.
unsafeOnSortedList :: ([a] -> [b]) -> (SortedList a -> SortedList b)

-- | Every diagram comes equipped with a <i>trace</i>. Intuitively, the
--   trace for a diagram is like a raytracer: given a line (represented as
--   a base point and a direction vector), the trace computes a sorted list
--   of signed distances from the base point to all intersections of the
--   line with the boundary of the diagram.
--   
--   Note that the outputs are not absolute distances, but multipliers
--   relative to the input vector. That is, if the base point is <tt>p</tt>
--   and direction vector is <tt>v</tt>, and one of the output scalars is
--   <tt>s</tt>, then there is an intersection at the point <tt>p .+^ (s *^
--   v)</tt>.
--   
newtype Trace v
Trace :: (Point v -> v -> SortedList (Scalar v)) -> Trace v
appTrace :: Trace v -> Point v -> v -> SortedList (Scalar v)
mkTrace :: (Point v -> v -> SortedList (Scalar v)) -> Trace v

-- | <tt>Traced</tt> abstracts over things which have a trace.
class (Ord (Scalar (V a)), VectorSpace (V a)) => Traced a
getTrace :: Traced a => a -> Trace (V a)

-- | Compute the vector from the given point <tt>p</tt> to the "smallest"
--   boundary intersection along the given vector <tt>v</tt>. The
--   "smallest" boundary intersection is defined as the one given by <tt>p
--   .+^ (s *^ v)</tt> for the smallest (most negative) value of
--   <tt>s</tt>. Return <tt>Nothing</tt> if there is no intersection. See
--   also <a>traceP</a>.
--   
--   See also <a>rayTraceV</a> which uses the smallest <i>positive</i>
--   intersection, which is often more intuitive behavior.
--   
traceV :: Traced a => Point (V a) -> V a -> a -> Maybe (V a)

-- | Compute the "smallest" boundary point along the line determined by the
--   given point <tt>p</tt> and vector <tt>v</tt>. The "smallest" boundary
--   point is defined as the one given by <tt>p .+^ (s *^ v)</tt> for the
--   smallest (most negative) value of <tt>s</tt>. Return <tt>Nothing</tt>
--   if there is no such boundary point. See also <a>traceV</a>.
--   
--   See also <a>rayTraceP</a> which uses the smallest <i>positive</i>
--   intersection, which is often more intuitive behavior.
--   
traceP :: Traced a => Point (V a) -> V a -> a -> Maybe (Point (V a))

-- | Like <a>traceV</a>, but computes a vector to the "largest" boundary
--   point instead of the smallest. (Note, however, the "largest" boundary
--   point may still be in the opposite direction from the given vector, if
--   all the boundary points are, as in the third example shown below.)
--   
maxTraceV :: Traced a => Point (V a) -> V a -> a -> Maybe (V a)

-- | Like <a>traceP</a>, but computes the "largest" boundary point instead
--   of the smallest. (Note, however, the "largest" boundary point may
--   still be in the opposite direction from the given vector, if all the
--   boundary points are.)
--   
maxTraceP :: Traced a => Point (V a) -> V a -> a -> Maybe (Point (V a))

-- | Get a modified <a>Trace</a> for an object which only returns positive
--   boundary points, <i>i.e.</i> those boundary points given by a positive
--   scalar multiple of the direction vector. Note, this property will be
--   destroyed if the resulting <a>Trace</a> is translated at all.
getRayTrace :: (Traced a, Num (Scalar (V a))) => a -> Trace (V a)

-- | Compute the vector from the given point to the closest boundary point
--   of the given object in the given direction, or <tt>Nothing</tt> if
--   there is no such boundary point (as in the third example below). Note
--   that unlike <a>traceV</a>, only <i>positive</i> boundary points are
--   considered, <i>i.e.</i> boundary points corresponding to a positive
--   scalar multiple of the direction vector. This is intuitively the
--   "usual" behavior of a raytracer, which only considers intersections
--   "in front of" the camera. Compare the second example diagram below
--   with the second example shown for <a>traceV</a>.
--   
rayTraceV :: (Traced a, Num (Scalar (V a))) => Point (V a) -> V a -> a -> Maybe (V a)

-- | Compute the boundary point on an object which is closest to the given
--   base point in the given direction, or <tt>Nothing</tt> if there is no
--   such boundary point. Note that unlike <a>traceP</a>, only
--   <i>positive</i> boundary points are considered, <i>i.e.</i> boundary
--   points corresponding to a positive scalar multiple of the direction
--   vector. This is intuitively the "usual" behavior of a raytracer, which
--   only considers intersection points "in front of" the camera.
--   
rayTraceP :: (Traced a, Num (Scalar (V a))) => Point (V a) -> V a -> a -> Maybe (Point (V a))

-- | Like <a>rayTraceV</a>, but computes a vector to the "largest" boundary
--   point instead of the smallest. Considers only <i>positive</i> boundary
--   points.
--   
maxRayTraceV :: (Traced a, Num (Scalar (V a))) => Point (V a) -> V a -> a -> Maybe (V a)

-- | Like <a>rayTraceP</a>, but computes the "largest" boundary point
--   instead of the smallest. Considers only <i>positive</i> boundary
--   points.
--   
maxRayTraceP :: (Traced a, Num (Scalar (V a))) => Point (V a) -> V a -> a -> Maybe (Point (V a))
instance Ord (Scalar v) => Monoid (Trace v)
instance Ord (Scalar v) => Semigroup (Trace v)
instance Traced b => Traced (Set b)
instance Traced b => Traced (Map k b)
instance Traced b => Traced [b]
instance (Traced a, Traced b, V a ~ V b) => Traced (a, b)
instance Traced t => Traced (TransInv t)
instance (Ord (Scalar v), VectorSpace v) => Traced (Point v)
instance (Ord (Scalar v), VectorSpace v) => Traced (Trace v)
instance HasLinearMap v => Transformable (Trace v)
instance Show (Trace v)
instance VectorSpace v => HasOrigin (Trace v)
instance Rewrapped (Trace v) (Trace v')
instance Wrapped (Trace v)
instance Ord a => Monoid (SortedList a)
instance Ord a => Semigroup (SortedList a)


-- | <a>Graphics.Rendering.Diagrams</a> defines the core library of
--   primitives forming the basis of an embedded domain-specific language
--   for describing and rendering diagrams.
--   
--   The <tt>Envelope</tt> module defines a data type and type class for
--   "envelopes", aka functional bounding regions.
module Diagrams.Core.Envelope

-- | Every diagram comes equipped with an <i>envelope</i>. What is an
--   envelope?
--   
--   Consider first the idea of a <i>bounding box</i>. A bounding box
--   expresses the distance to a bounding plane in every direction parallel
--   to an axis. That is, a bounding box can be thought of as the
--   intersection of a collection of half-planes, two perpendicular to each
--   axis.
--   
--   More generally, the intersection of half-planes in <i>every</i>
--   direction would give a tight "bounding region", or convex hull.
--   However, representing such a thing intensionally would be impossible;
--   hence bounding boxes are often used as an approximation.
--   
--   An envelope is an <i>extensional</i> representation of such a
--   "bounding region". Instead of storing some sort of direct
--   representation, we store a <i>function</i> which takes a direction as
--   input and gives a distance to a bounding half-plane as output. The
--   important point is that envelopes can be composed, and transformed by
--   any affine transformation.
--   
--   Formally, given a vector <tt>v</tt>, the envelope computes a scalar
--   <tt>s</tt> such that
--   
--   <ul>
--   <li>for every point <tt>u</tt> inside the diagram, if the projection
--   of <tt>(u - origin)</tt> onto <tt>v</tt> is <tt>s' *^ v</tt>, then
--   <tt>s' &lt;= s</tt>.</li>
--   <li><tt>s</tt> is the smallest such scalar.</li>
--   </ul>
--   
--   There is also a special "empty envelope".
--   
--   The idea for envelopes came from Sebastian Setzer; see
--   <a>http://byorgey.wordpress.com/2009/10/28/collecting-attributes/#comment-2030</a>.
--   See also Brent Yorgey, <i>Monoids: Theme and Variations</i>, published
--   in the 2012 Haskell Symposium:
--   <a>http://www.cis.upenn.edu/~byorgey/pub/monoid-pearl.pdf</a>; video:
--   <a>http://www.youtube.com/watch?v=X-8NCkD2vOw</a>.
newtype Envelope v
Envelope :: (Option (v -> Max (Scalar v))) -> Envelope v
appEnvelope :: Envelope v -> Maybe (v -> Scalar v)
onEnvelope :: ((v -> Scalar v) -> (v -> Scalar v)) -> Envelope v -> Envelope v
mkEnvelope :: (v -> Scalar v) -> Envelope v

-- | Create an envelope for the given point.
pointEnvelope :: (Fractional (Scalar v), InnerSpace v) => Point v -> Envelope v

-- | <tt>Enveloped</tt> abstracts over things which have an envelope.
class (InnerSpace (V a), OrderedField (Scalar (V a))) => Enveloped a
getEnvelope :: Enveloped a => a -> Envelope (V a)

-- | Compute the diameter of a enveloped object along a particular vector.
--   Returns zero for the empty envelope.
diameter :: Enveloped a => V a -> a -> Scalar (V a)

-- | Compute the "radius" (1/2 the diameter) of an enveloped object along a
--   particular vector.
radius :: Enveloped a => V a -> a -> Scalar (V a)

-- | Compute the range of an enveloped object along a certain direction.
--   Returns a pair of scalars <tt>(lo,hi)</tt> such that the object
--   extends from <tt>(lo *^ v)</tt> to <tt>(hi *^ v)</tt>. Returns
--   <tt>Nothing</tt> for objects with an empty envelope.
extent :: Enveloped a => V a -> a -> Maybe (Scalar (V a), Scalar (V a))

-- | Compute the vector from the local origin to a separating hyperplane in
--   the given direction, or <tt>Nothing</tt> for the empty envelope.
envelopeVMay :: Enveloped a => V a -> a -> Maybe (V a)

-- | Compute the vector from the local origin to a separating hyperplane in
--   the given direction. Returns the zero vector for the empty envelope.
envelopeV :: Enveloped a => V a -> a -> V a

-- | Compute the point on a separating hyperplane in the given direction,
--   or <tt>Nothing</tt> for the empty envelope.
envelopePMay :: Enveloped a => V a -> a -> Maybe (Point (V a))

-- | Compute the point on a separating hyperplane in the given direction.
--   Returns the origin for the empty envelope.
envelopeP :: Enveloped a => V a -> a -> Point (V a)

-- | Equivalent to the magnitude of <a>envelopeVMay</a>:
--   
--   <pre>
--   envelopeSMay v x == fmap magnitude (envelopeVMay v x)
--   </pre>
--   
--   (other than differences in rounding error)
--   
--   Note that the <a>envelopeVMay</a> / <a>envelopePMay</a> functions
--   above should be preferred, as this requires a call to magnitude.
--   However, it is more efficient than calling magnitude on the results of
--   those functions.
envelopeSMay :: Enveloped a => V a -> a -> Maybe (Scalar (V a))

-- | Equivalent to the magnitude of <a>envelopeV</a>:
--   
--   <pre>
--   envelopeS v x == magnitude (envelopeV v x)
--   </pre>
--   
--   (other than differences in rounding error)
--   
--   Note that the <a>envelopeV</a> / <a>envelopeP</a> functions above
--   should be preferred, as this requires a call to magnitude. However, it
--   is more efficient than calling magnitude on the results of those
--   functions.
envelopeS :: (Enveloped a, Num (Scalar (V a))) => V a -> a -> Scalar (V a)

-- | When dealing with envelopes we often want scalars to be an ordered
--   field (i.e. support all four arithmetic operations and be totally
--   ordered) so we introduce this class as a convenient shorthand.
class (Fractional s, Floating s, Ord s, AdditiveGroup s) => OrderedField s
instance Ord (Scalar v) => Monoid (Envelope v)
instance Ord (Scalar v) => Semigroup (Envelope v)
instance Enveloped b => Enveloped (Set b)
instance Enveloped b => Enveloped (Map k b)
instance Enveloped b => Enveloped [b]
instance (Enveloped a, Enveloped b, V a ~ V b) => Enveloped (a, b)
instance Enveloped t => Enveloped (TransInv t)
instance (OrderedField (Scalar v), InnerSpace v) => Enveloped (Point v)
instance (InnerSpace v, OrderedField (Scalar v)) => Enveloped (Envelope v)
instance (Fractional s, Floating s, Ord s, AdditiveGroup s) => OrderedField s
instance (HasLinearMap v, InnerSpace v, Floating (Scalar v)) => Transformable (Envelope v)
instance Show (Envelope v)
instance (InnerSpace v, Fractional (Scalar v)) => HasOrigin (Envelope v)
instance Rewrapped (Envelope v) (Envelope v')
instance Wrapped (Envelope v)


-- | Things which can be placed "next to" other things, for some
--   appropriate notion of "next to".
module Diagrams.Core.Juxtapose

-- | Class of things which can be placed "next to" other things, for some
--   appropriate notion of "next to".
class Juxtaposable a
juxtapose :: Juxtaposable a => V a -> a -> a -> a

-- | Default implementation of <a>juxtapose</a> for things which are
--   instances of <a>Enveloped</a> and <a>HasOrigin</a>. If either envelope
--   is empty, the second object is returned unchanged.
juxtaposeDefault :: (Enveloped a, HasOrigin a) => V a -> a -> a -> a
instance Juxtaposable a => Juxtaposable (b -> a)
instance (Enveloped b, HasOrigin b, Ord b) => Juxtaposable (Set b)
instance (Enveloped b, HasOrigin b) => Juxtaposable (Map k b)
instance (Enveloped b, HasOrigin b) => Juxtaposable [b]
instance (Enveloped a, HasOrigin a, Enveloped b, HasOrigin b, V a ~ V b) => Juxtaposable (a, b)
instance (InnerSpace v, OrderedField (Scalar v)) => Juxtaposable (Envelope v)


-- | The core library of primitives forming the basis of an embedded
--   domain-specific language for describing and rendering diagrams.
--   
--   <a>Diagrams.Core.Types</a> defines types and classes for primitives,
--   diagrams, and backends.
module Diagrams.Core.Types

-- | Static annotations which can be placed at a particular node of a
--   diagram tree.
data Annotation

-- | Hyperlink
Href :: String -> Annotation

-- | Apply a static annotation at the root of a diagram.
applyAnnotation :: (HasLinearMap v, InnerSpace v, OrderedField (Scalar v), Semigroup m) => Annotation -> QDiagram b v m -> QDiagram b v m

-- | Make a diagram into a hyperlink. Note that only some backends will
--   honor hyperlink annotations.
href :: (HasLinearMap v, InnerSpace v, OrderedField (Scalar v), Semigroup m) => String -> QDiagram b v m -> QDiagram b v m

-- | Monoidal annotations which travel up the diagram tree, <i>i.e.</i>
--   which are aggregated from component diagrams to the whole:
--   
--   <ul>
--   <li>envelopes (see <a>Diagrams.Core.Envelope</a>). The envelopes are
--   "deletable" meaning that at any point we can throw away the existing
--   envelope and replace it with a new one; sometimes we want to consider
--   a diagram as having a different envelope unrelated to its "natural"
--   envelope.</li>
--   <li>traces (see <a>Diagrams.Core.Trace</a>), also deletable.</li>
--   <li>name/subdiagram associations (see <a>Diagrams.Core.Names</a>)</li>
--   <li>query functions (see <a>Diagrams.Core.Query</a>)</li>
--   </ul>
type UpAnnots b v m = Deletable (Envelope v) ::: (Deletable (Trace v) ::: (Deletable (SubMap b v m) ::: (Query v m ::: ())))

-- | Monoidal annotations which travel down the diagram tree, <i>i.e.</i>
--   which accumulate along each path to a leaf (and which can act on the
--   upwards-travelling annotations):
--   
--   <ul>
--   <li>styles (see <a>Diagrams.Core.Style</a>)</li>
--   <li>names (see <a>Diagrams.Core.Names</a>)</li>
--   </ul>
type DownAnnots v = (Transformation v :+: Style v) ::: (Name ::: ())

-- | Inject a transformation into a default downwards annotation value.
transfToAnnot :: Transformation v -> DownAnnots v

-- | Extract the (total) transformation from a downwards annotation value.
transfFromAnnot :: HasLinearMap v => DownAnnots v -> Transformation v

-- | A leaf in a <a>QDiagram</a> tree is either a <a>Prim</a>, or a
--   "delayed" <tt>QDiagram</tt> which expands to a real <tt>QDiagram</tt>
--   once it learns the "final context" in which it will be rendered. For
--   example, in order to decide how to draw an arrow, we must know the
--   precise transformation applied to it (since the arrow head and tail
--   are scale-invariant).
data QDiaLeaf b v m
PrimLeaf :: (Prim b v) -> QDiaLeaf b v m

-- | The <tt>QDiagram</tt> produced by a <tt>DelayedLeaf</tt> function
--   <i>must</i> already apply any transformation in the given
--   <tt>DownAnnots</tt> (that is, the transformation will not be applied
--   by the context).
DelayedLeaf :: (DownAnnots v -> Scalar v -> Scalar v -> QDiagram b v m) -> QDiaLeaf b v m
withQDiaLeaf :: (Prim b v -> r) -> ((DownAnnots v -> Scalar v -> Scalar v -> QDiagram b v m) -> r) -> (QDiaLeaf b v m -> r)

-- | The fundamental diagram type. The type variables are as follows:
--   
--   <ul>
--   <li><tt>b</tt> represents the backend, such as <tt>SVG</tt> or
--   <tt>Cairo</tt>. Note that each backend also exports a type synonym
--   <tt>B</tt> for itself, so the type variable <tt>b</tt> may also
--   typically be instantiated by <tt>B</tt>, meaning "use whatever backend
--   is in scope".</li>
--   <li><tt>v</tt> represents the vector space of the diagram. Typical
--   instantiations include <tt>R2</tt> (for a two-dimensional diagram) or
--   <tt>R3</tt> (for a three-dimensional diagram).</li>
--   <li><tt>m</tt> is the monoidal type of "query annotations": each point
--   in the diagram has a value of type <tt>m</tt> associated to it, and
--   these values are combined according to the <a>Monoid</a> instance for
--   <tt>m</tt>. Most often, <tt>m</tt> is simply instantiated to
--   <a>Any</a>, associating a simple <tt>Bool</tt> value to each point
--   indicating whether the point is inside the diagram; <a>Diagram</a> is
--   a synonym for <tt>QDiagram</tt> with <tt>m</tt> thus instantiated to
--   <tt>Any</tt>.</li>
--   </ul>
--   
--   Diagrams can be combined via their <a>Monoid</a> instance, transformed
--   via their <a>Transformable</a> instance, and assigned attributes via
--   their <a>HasStyle</a> instance.
--   
--   Note that the <tt>Q</tt> in <tt>QDiagram</tt> stands for "Queriable",
--   as distinguished from <a>Diagram</a>, where <tt>m</tt> is fixed to
--   <tt>Any</tt>. This is not really a very good name, but it's probably
--   not worth changing it at this point.
newtype QDiagram b v m
QD :: (DUALTree (DownAnnots v) (UpAnnots b v m) Annotation (QDiaLeaf b v m)) -> QDiagram b v m

-- | <tt>Diagram b v</tt> is a synonym for <tt><a>QDiagram</a> b v
--   <a>Any</a></tt>. That is, the default sort of diagram is one where
--   querying at a point simply tells you whether the diagram contains that
--   point or not. Transforming a default diagram into one with a more
--   interesting query can be done via the <a>Functor</a> instance of
--   <tt><a>QDiagram</a> b</tt> or the <a>value</a> function.
type Diagram b v = QDiagram b v Any

-- | Create a diagram from a single primitive, along with an envelope,
--   trace, subdiagram map, and query function.
mkQD :: Prim b v -> Envelope v -> Trace v -> SubMap b v m -> Query v m -> QDiagram b v m

-- | Create a diagram from a generic QDiaLeaf, along with an envelope,
--   trace, subdiagram map, and query function.
mkQD' :: QDiaLeaf b v m -> Envelope v -> Trace v -> SubMap b v m -> Query v m -> QDiagram b v m

-- | Create a "point diagram", which has no content, no trace, an empty
--   query, and a point envelope.
pointDiagram :: (Fractional (Scalar v), InnerSpace v) => Point v -> QDiagram b v m

-- | Get the envelope of a diagram.
envelope :: (OrderedField (Scalar v), InnerSpace v, HasLinearMap v, Monoid' m) => Lens' (QDiagram b v m) (Envelope v)

-- | Get the trace of a diagram.
trace :: (InnerSpace v, HasLinearMap v, OrderedField (Scalar v), Semigroup m) => Lens' (QDiagram b v m) (Trace v)

-- | Get the subdiagram map (<i>i.e.</i> an association from names to
--   subdiagrams) of a diagram.
subMap :: (HasLinearMap v, InnerSpace v, Semigroup m, OrderedField (Scalar v)) => Lens' (QDiagram b v m) (SubMap b v m)

-- | Get a list of names of subdiagrams and their locations.
names :: (HasLinearMap v, InnerSpace v, Semigroup m, OrderedField (Scalar v)) => QDiagram b v m -> [(Name, [Point v])]

-- | Get the query function associated with a diagram.
query :: Monoid m => QDiagram b v m -> Query v m

-- | Sample a diagram's query function at a given point.
sample :: Monoid m => QDiagram b v m -> Point v -> m

-- | Set the query value for <a>True</a> points in a diagram (<i>i.e.</i>
--   points "inside" the diagram); <a>False</a> points will be set to
--   <a>mempty</a>.
value :: Monoid m => m -> QDiagram b v Any -> QDiagram b v m

-- | Reset the query values of a diagram to <tt>True</tt>/<tt>False</tt>:
--   any values equal to <a>mempty</a> are set to <a>False</a>; any other
--   values are set to <a>True</a>.
resetValue :: (Eq m, Monoid m) => QDiagram b v m -> QDiagram b v Any

-- | Set all the query values of a diagram to <a>False</a>.
clearValue :: QDiagram b v m -> QDiagram b v Any

-- | A convenient synonym for <a>mappend</a> on diagrams, designed to be
--   used infix (to help remember which diagram goes on top of which when
--   combining them, namely, the first on top of the second).
atop :: (HasLinearMap v, OrderedField (Scalar v), InnerSpace v, Semigroup m) => QDiagram b v m -> QDiagram b v m -> QDiagram b v m

-- | Attach an atomic name to a certain subdiagram, computed from the given
--   diagram /with the mapping from name to subdiagram included/. The
--   upshot of this knot-tying is that if <tt>d' = d # named x</tt>, then
--   <tt>lookupName x d' == Just d'</tt> (instead of <tt>Just d</tt>).
nameSub :: (IsName n, HasLinearMap v, InnerSpace v, OrderedField (Scalar v), Semigroup m) => (QDiagram b v m -> Subdiagram b v m) -> n -> QDiagram b v m -> QDiagram b v m

-- | Lookup the most recent diagram associated with (some qualification of)
--   the given name.
lookupName :: (IsName n, HasLinearMap v, InnerSpace v, Semigroup m, OrderedField (Scalar v)) => n -> QDiagram b v m -> Maybe (Subdiagram b v m)

-- | Given a name and a diagram transformation indexed by a subdiagram,
--   perform the transformation using the most recent subdiagram associated
--   with (some qualification of) the name, or perform the identity
--   transformation if the name does not exist.
withName :: (IsName n, HasLinearMap v, InnerSpace v, Semigroup m, OrderedField (Scalar v)) => n -> (Subdiagram b v m -> QDiagram b v m -> QDiagram b v m) -> QDiagram b v m -> QDiagram b v m

-- | Given a name and a diagram transformation indexed by a list of
--   subdiagrams, perform the transformation using the collection of all
--   such subdiagrams associated with (some qualification of) the given
--   name.
withNameAll :: (IsName n, HasLinearMap v, InnerSpace v, Semigroup m, OrderedField (Scalar v)) => n -> ([Subdiagram b v m] -> QDiagram b v m -> QDiagram b v m) -> QDiagram b v m -> QDiagram b v m

-- | Given a list of names and a diagram transformation indexed by a list
--   of subdiagrams, perform the transformation using the list of most
--   recent subdiagrams associated with (some qualification of) each name.
--   Do nothing (the identity transformation) if any of the names do not
--   exist.
withNames :: (IsName n, HasLinearMap v, InnerSpace v, Semigroup m, OrderedField (Scalar v)) => [n] -> ([Subdiagram b v m] -> QDiagram b v m -> QDiagram b v m) -> QDiagram b v m -> QDiagram b v m

-- | "Localize" a diagram by hiding all the names, so they are no longer
--   visible to the outside.
localize :: (HasLinearMap v, InnerSpace v, OrderedField (Scalar v), Semigroup m) => QDiagram b v m -> QDiagram b v m

-- | Replace the envelope of a diagram.
setEnvelope :: (OrderedField (Scalar v), InnerSpace v, HasLinearMap v, Monoid' m) => Envelope v -> QDiagram b v m -> QDiagram b v m

-- | Replace the trace of a diagram.
setTrace :: (OrderedField (Scalar v), InnerSpace v, HasLinearMap v, Semigroup m) => Trace v -> QDiagram b v m -> QDiagram b v m

-- | Type of measurement units for attributes.
data Measure v
Output :: (Scalar v) -> Measure v
Normalized :: (Scalar v) -> Measure v
Local :: (Scalar v) -> Measure v
Global :: (Scalar v) -> Measure v
MinM :: (Measure v) -> (Measure v) -> Measure v
MaxM :: (Measure v) -> (Measure v) -> Measure v
ZeroM :: Measure v
NegateM :: (Measure v) -> Measure v
PlusM :: (Measure v) -> (Measure v) -> Measure v
ScaleM :: (Scalar v) -> (Measure v) -> Measure v

-- | Retrieve the <a>Output</a> value of a 'Measure v' or throw an
--   exception. Only <tt>Ouput</tt> measures should be left in the
--   <a>RTree</a> passed to the backend.
fromOutput :: Measure v -> Scalar v

-- | Compute the smaller of two <a>Measure</a>s. Useful for setting upper
--   bounds.
atMost :: Measure v -> Measure v -> Measure v

-- | Compute the larger of two <a>Measure</a>s. Useful for setting lower
--   bounds.
atLeast :: Measure v -> Measure v -> Measure v

-- | A <tt>Subdiagram</tt> represents a diagram embedded within the context
--   of a larger diagram. Essentially, it consists of a diagram paired with
--   any accumulated information from the larger context (transformations,
--   attributes, etc.).
data Subdiagram b v m
Subdiagram :: (QDiagram b v m) -> (DownAnnots v) -> Subdiagram b v m

-- | Turn a diagram into a subdiagram with no accumulated context.
mkSubdiagram :: QDiagram b v m -> Subdiagram b v m

-- | Turn a subdiagram into a normal diagram, including the enclosing
--   context. Concretely, a subdiagram is a pair of (1) a diagram and (2) a
--   "context" consisting of an extra transformation and attributes.
--   <tt>getSub</tt> simply applies the transformation and attributes to
--   the diagram to get the corresponding "top-level" diagram.
getSub :: (HasLinearMap v, InnerSpace v, Floating (Scalar v), Ord (Scalar v), Semigroup m) => Subdiagram b v m -> QDiagram b v m

-- | Extract the "raw" content of a subdiagram, by throwing away the
--   context.
rawSub :: Subdiagram b v m -> QDiagram b v m

-- | Get the location of a subdiagram; that is, the location of its local
--   origin <i>with respect to</i> the vector space of its parent diagram.
--   In other words, the point where its local origin "ended up".
location :: HasLinearMap v => Subdiagram b v m -> Point v

-- | Create a "point subdiagram", that is, a <a>pointDiagram</a> (with no
--   content and a point envelope) treated as a subdiagram with local
--   origin at the given point. Note this is not the same as
--   <tt>mkSubdiagram . pointDiagram</tt>, which would result in a
--   subdiagram with local origin at the parent origin, rather than at the
--   given point.
subPoint :: (HasLinearMap v, InnerSpace v, OrderedField (Scalar v), Semigroup m) => Point v -> Subdiagram b v m

-- | A <a>SubMap</a> is a map associating names to subdiagrams. There can
--   be multiple associations for any given name.
newtype SubMap b v m
SubMap :: (Map Name [Subdiagram b v m]) -> SubMap b v m

-- | Construct a <a>SubMap</a> from a list of associations between names
--   and subdiagrams.
fromNames :: IsName a => [(a, Subdiagram b v m)] -> SubMap b v m

-- | Add a name/diagram association to a submap.
rememberAs :: IsName a => a -> QDiagram b v m -> SubMap b v m -> SubMap b v m

-- | Look for the given name in a name map, returning a list of subdiagrams
--   associated with that name. If no names match the given name exactly,
--   return all the subdiagrams associated with names of which the given
--   name is a suffix.
lookupSub :: IsName n => n -> SubMap b v m -> Maybe [Subdiagram b v m]

-- | A value of type <tt>Prim b v</tt> is an opaque (existentially
--   quantified) primitive which backend <tt>b</tt> knows how to render in
--   vector space <tt>v</tt>.
data Prim b v
Prim :: p -> Prim b (V p)

-- | Abstract diagrams are rendered to particular formats by
--   <i>backends</i>. Each backend/vector space combination must be an
--   instance of the <a>Backend</a> class.
--   
--   A minimal complete definition consists of <a>Render</a>,
--   <a>Result</a>, <a>Options</a>, and <a>renderRTree</a>. However, most
--   backends will want to implement <a>adjustDia</a> as well; the default
--   definition does nothing. Some useful standard definitions are provided
--   in the <tt>Diagrams.TwoD.Adjust</tt> module from the
--   <tt>diagrams-lib</tt> package.
class HasLinearMap v => Backend b v where data family Render b v :: * type family Result b v :: * data family Options b v :: * adjustDia _ o d = (o, mempty, d)
adjustDia :: (Backend b v, Monoid' m, Num (Scalar v)) => b -> Options b v -> QDiagram b v m -> (Options b v, Transformation v, QDiagram b v m)
renderRTree :: Backend b v => b -> Options b v -> RTree b v Annotation -> Result b v
data DNode b v a
DStyle :: (Style v) -> DNode b v a
DTransform :: (Transformation v) -> DNode b v a
DAnnot :: a -> DNode b v a

-- | <tt>DDelay</tt> marks a point where a delayed subtree was expanded.
--   Such subtrees already take all non-frozen transforms above them into
--   account, so when later processing the tree, upon encountering a
--   <tt>DDelay</tt> node we must drop any accumulated non-frozen
--   transformation.
DDelay :: DNode b v a
DPrim :: (Prim b v) -> DNode b v a
DEmpty :: DNode b v a

-- | A <a>DTree</a> is a raw tree representation of a <a>QDiagram</a>, with
--   all the <tt>u</tt>-annotations removed. It is used as an intermediate
--   type by diagrams-core; backends should not need to make use of it.
--   Instead, backends can make use of <a>RTree</a>, which <a>DTree</a>
--   gets compiled and optimized to.
type DTree b v a = Tree (DNode b v a)
data RNode b v a

-- | A style node.
RStyle :: (Style v) -> RNode b v a
RAnnot :: a -> RNode b v a

-- | A primitive.
RPrim :: (Prim b v) -> RNode b v a
REmpty :: RNode b v a

-- | An <a>RTree</a> is a compiled and optimized representation of a
--   <a>QDiagram</a>, which can be used by backends. They have the
--   following invariant which backends may rely upon:
--   
--   <ul>
--   <li><tt>RPrim</tt> nodes never have any children.</li>
--   </ul>
type RTree b v a = Tree (RNode b v a)

-- | A null backend which does no actual rendering. It is provided mainly
--   for convenience in situations where you must give a diagram a
--   concrete, monomorphic type, but don't actually care which one. See
--   <a>D</a> for more explanation and examples.
--   
--   It is courteous, when defining a new primitive <tt>P</tt>, to make an
--   instance
--   
--   <pre>
--   instance Renderable P NullBackend where
--     render _ _ = mempty
--   </pre>
--   
--   This ensures that the trick with <a>D</a> annotations can be used for
--   diagrams containing your primitive.
data NullBackend

-- | The <tt>D</tt> type is provided for convenience in situations where
--   you must give a diagram a concrete, monomorphic type, but don't care
--   which one. Such situations arise when you pass a diagram to a function
--   which is polymorphic in its input but monomorphic in its output, such
--   as <tt>width</tt>, <tt>height</tt>, <tt>phantom</tt>, or <a>names</a>.
--   Such functions compute some property of the diagram, or use it to
--   accomplish some other purpose, but do not result in the diagram being
--   rendered. If the diagram does not have a monomorphic type, GHC
--   complains that it cannot determine the diagram's type.
--   
--   For example, here is the error we get if we try to compute the width
--   of an image (this example requires <tt>diagrams-lib</tt>):
--   
--   <pre>
--   ghci&gt; width (image "foo.png" 200 200)
--   &lt;interactive&gt;:8:8:
--       No instance for (Renderable Diagrams.TwoD.Image.Image b0)
--         arising from a use of <tt>image</tt>
--       Possible fix:
--         add an instance declaration for
--         (Renderable Diagrams.TwoD.Image.Image b0)
--       In the first argument of <tt>width</tt>, namely
--         `(image "foo.png" 200 200)'
--       In the expression: width (image "foo.png" 200 200)
--       In an equation for <tt>it</tt>: it = width (image "foo.png" 200 200)
--   </pre>
--   
--   GHC complains that there is no instance for <tt>Renderable Image
--   b0</tt>; what is really going on is that it does not have enough
--   information to decide what backend to use (hence the uninstantiated
--   <tt>b0</tt>). This is annoying because <i>we</i> know that the choice
--   of backend cannot possibly affect the width of the image (it's 200!
--   it's right there in the code!); <i>but</i> there is no way for GHC to
--   know that.
--   
--   The solution is to annotate the call to <tt>image</tt> with the type
--   <tt><a>D</a> <tt>R2</tt></tt>, like so:
--   
--   <pre>
--   ghci&gt; width (image "foo.png" 200 200 :: D R2)
--   200.00000000000006
--   </pre>
--   
--   (It turns out the width wasn't 200 after all...)
--   
--   As another example, here is the error we get if we try to compute the
--   width of a radius-1 circle:
--   
--   <pre>
--   ghci&gt; width (circle 1)
--   &lt;interactive&gt;:4:1:
--       Couldn't match type `V a0' with <tt>R2</tt>
--       In the expression: width (circle 1)
--       In an equation for <tt>it</tt>: it = width (circle 1)
--   </pre>
--   
--   There's even more ambiguity here. Whereas <tt>image</tt> always
--   returns a <a>Diagram</a>, the <tt>circle</tt> function can produce any
--   <tt>PathLike</tt> type, and the <tt>width</tt> function can consume
--   any <a>Enveloped</a> type, so GHC has no idea what type to pick to go
--   in the middle. However, the solution is the same:
--   
--   <pre>
--   ghci&gt; width (circle 1 :: D R2)
--   1.9999999999999998
--   </pre>
type D v = Diagram NullBackend v

-- | The Renderable type class connects backends to primitives which they
--   know how to render.
class Transformable t => Renderable t b
render :: Renderable t b => b -> t -> Render b (V t)
instance Typeable1 Measure
instance Typeable3 QDiagram
instance (Typeable v, Data v, Data (Scalar v)) => Data (Measure v)
instance Show (Scalar v) => Show (Measure v)
instance Ord (Scalar v) => Ord (Measure v)
instance Eq (Scalar v) => Eq (Measure v)
instance Show Annotation
instance Functor (QDiaLeaf b v)
instance HasLinearMap v => Backend NullBackend v
instance Monoid (Render NullBackend v)
instance HasLinearMap v => Renderable (Prim b v) b
instance HasLinearMap v => Transformable (Prim b v)
instance Action Name (Trace v)
instance Action Name (Envelope v)
instance Action Name (Query v m)
instance Action Name a => Action Name (Deletable a)
instance Action Name (SubMap b v m)
instance Qualifiable (SubMap b v m)
instance (InnerSpace v, Floating (Scalar v), HasLinearMap v) => Transformable (SubMap b v m)
instance (OrderedField (Scalar v), InnerSpace v, HasLinearMap v) => HasOrigin (SubMap b v m)
instance Monoid (SubMap b v m)
instance Semigroup (SubMap b v m)
instance Functor (SubMap b v)
instance Rewrapped (SubMap b v m) (SubMap b' v' m')
instance Wrapped (SubMap b v m)
instance (HasLinearMap v, InnerSpace v, Floating (Scalar v)) => Transformable (Subdiagram b v m)
instance (HasLinearMap v, InnerSpace v, OrderedField (Scalar v)) => HasOrigin (Subdiagram b v m)
instance (OrderedField (Scalar v), HasLinearMap v, InnerSpace v, Semigroup m) => Traced (Subdiagram b v m)
instance (OrderedField (Scalar v), InnerSpace v, HasLinearMap v, Monoid' m) => Enveloped (Subdiagram b v m)
instance Functor (Subdiagram b v)
instance (HasLinearMap v, InnerSpace v, OrderedField (Scalar v), Semigroup m) => Qualifiable (QDiagram b v m)
instance (HasLinearMap v, OrderedField (Scalar v), InnerSpace v, Semigroup m) => Transformable (QDiagram b v m)
instance (HasLinearMap v, InnerSpace v, OrderedField (Scalar v), Semigroup m) => HasOrigin (QDiagram b v m)
instance (HasLinearMap v, VectorSpace v, Ord (Scalar v), InnerSpace v, Semigroup m, Fractional (Scalar v), Floating (Scalar v)) => Traced (QDiagram b v m)
instance (HasLinearMap v, InnerSpace v, OrderedField (Scalar v), Monoid' m) => Enveloped (QDiagram b v m)
instance (HasLinearMap v, InnerSpace v, OrderedField (Scalar v), Monoid' m) => Juxtaposable (QDiagram b v m)
instance (HasLinearMap v, InnerSpace v, OrderedField (Scalar v), Semigroup m) => HasStyle (QDiagram b v m)
instance Functor (QDiagram b v)
instance (HasLinearMap v, InnerSpace v, OrderedField (Scalar v), Semigroup m) => Semigroup (QDiagram b v m)
instance (HasLinearMap v, InnerSpace v, OrderedField (Scalar v), Semigroup m) => Monoid (QDiagram b v m)
instance Rewrapped (QDiagram b v m) (QDiagram b' v' m')
instance Wrapped (QDiagram b v m)
instance (HasLinearMap v, Floating (Scalar v)) => Transformable (Measure v)
instance VectorSpace (Measure v)
instance AdditiveGroup (Measure v)


-- | This module provides tools for compiling <tt>QDiagrams</tt> into a
--   more convenient and optimized tree form, suitable for use by backends.
module Diagrams.Core.Compile
data RNode b v a

-- | A style node.
RStyle :: (Style v) -> RNode b v a
RAnnot :: a -> RNode b v a

-- | A primitive.
RPrim :: (Prim b v) -> RNode b v a
REmpty :: RNode b v a

-- | An <a>RTree</a> is a compiled and optimized representation of a
--   <a>QDiagram</a>, which can be used by backends. They have the
--   following invariant which backends may rely upon:
--   
--   <ul>
--   <li><tt>RPrim</tt> nodes never have any children.</li>
--   </ul>
type RTree b v a = Tree (RNode b v a)

-- | Compile a <tt>QDiagram</tt> into an <a>RTree</a>, rewriting styles
--   with the given function along the way. Suitable for use by backends
--   when implementing <tt>renderData</tt>. The first argument is the
--   transformation used to convert the diagram from local to output units.
toRTree :: (HasLinearMap v, InnerSpace v, Data v, Data (Scalar v), OrderedField (Scalar v), Monoid m, Semigroup m) => Transformation v -> QDiagram b v m -> RTree b v Annotation

-- | Render a diagram.
renderDia :: (Backend b v, InnerSpace v, Data v, OrderedField (Scalar v), Data (Scalar v), Monoid' m) => b -> Options b v -> QDiagram b v m -> Result b v

-- | Render a diagram, returning also the transformation which was used to
--   convert the diagram from its ("global") coordinate system into the
--   output coordinate system. The inverse of this transformation can be
--   used, for example, to convert output/screen coordinates back into
--   diagram coordinates. See also <a>adjustDia</a>.
renderDiaT :: (Backend b v, HasLinearMap v, InnerSpace v, Data v, OrderedField (Scalar v), Data (Scalar v), Monoid' m) => b -> Options b v -> QDiagram b v m -> (Transformation v, Result b v)

-- | Convert a <tt>QDiagram</tt> into a raw tree.
toDTree :: HasLinearMap v => Scalar v -> Scalar v -> QDiagram b v m -> Maybe (DTree b v Annotation)

-- | Convert a <tt>DTree</tt> to an <tt>RTree</tt> which can be used
--   dirctly by backends. A <tt>DTree</tt> includes nodes of type
--   <tt>DTransform (Transformation v)</tt>; in the <tt>RTree</tt>
--   transform is pushed down until it reaches a primitive node.
fromDTree :: HasLinearMap v => DTree b v Annotation -> RTree b v Annotation

-- | Convert all <a>Measure</a> values to <a>Output</a> units. The
--   arguments are, respectively, the scaling factor from global units to
--   output units, and from normalized units to output units. It is assumed
--   that local units are identical to output units (which will be the case
--   if all transformations have been fully pushed down and applied).
--   Normalized units are based on a logical diagram size of 1 x 1.
styleToOutput :: (Data v, Data (Scalar v), Num (Scalar v), Ord (Scalar v), Fractional (Scalar v)) => Scalar v -> Scalar v -> Style v -> Style v

-- | Convert an aribrary <a>Measure</a> to <a>Output</a> units.
toOutput :: (Data v, Data (Scalar v), Num (Scalar v), Ord (Scalar v), Fractional (Scalar v)) => Scalar v -> Scalar v -> Measure v -> Measure v


-- | The core library of primitives forming the basis of an embedded
--   domain-specific language for describing and rendering diagrams. Normal
--   users of the diagrams library should almost never need to import
--   anything from this package directly; instead, import modules
--   (especially <tt>Diagrams.Prelude</tt>) from the diagrams-lib package,
--   which re-exports most things of value to users.
--   
--   For most library code needing access to core internals, it should be
--   sufficient to import this module, which simply re-exports useful
--   functionality from other modules in the core library. Library writers
--   needing finer-grained access or functionality may occasionally find it
--   useful to directly import one of the constituent core modules.
--   
--   The diagrams library relies heavily on custom types and classes. Many
--   of the relevant definitions are in the <a>Diagrams.Core.Types</a>
--   module. Indeed the definition of the diagram type <tt>QDiagram</tt> is
--   contained in: <a>QDiagram</a>.
--   
--   The best place to start when learning about diagrams' types is the
--   user manual:
--   <a>http://projects.haskell.org/diagrams/doc/manual.html#type-reference</a>
--   The following list shows which types are contained in each module of
--   <a>Diagrams.Core</a>.
--   
--   <ul>
--   <li><a>Diagrams.Core.Types</a></li>
--   <li><tt>Annotation</tt>, * <tt>UpAnnots b v m</tt>, <tt>DownAnnots
--   v</tt>, * <tt>QDiaLeaf b v m</tt>, <tt>Measure v</tt>, *
--   <tt>Subdiagram b v m</tt>, <tt>SubMap b v m</tt>, * <tt>Prim b v</tt>,
--   <tt>Backend b v</tt>, * <tt>DNode b v a</tt>, <tt>DTree b v a</tt>, *
--   <tt>RNode b v a</tt>, <tt>RTree b v a</tt>, * <tt>NullBackend</tt>,
--   <tt>Renderable t b</tt>, * <tt>D v</tt>.</li>
--   <li><a>Diagrams.Core.Envelope</a></li>
--   <li><tt>Envelope v</tt>, <tt>Enveloped v</tt>, * <tt>OrderedField
--   s</tt>.</li>
--   <li><a>Diagrams.Core.Juxtapose</a></li>
--   <li><tt>Juxtaposable a</tt>.</li>
--   <li><a>Diagrams.Core.Names</a></li>
--   <li><tt>AName</tt>, <tt>Name</tt>, <tt>IsName a</tt>, *
--   <tt>Qualifiable q</tt>.</li>
--   <li><a>Diagrams.Core.HasOrigin</a></li>
--   <li><tt>HasOrigin t</tt>.</li>
--   <li><a>Diagrams.Core.Points</a></li>
--   <li><tt>Point v</tt>.</li>
--   <li><a>Diagrams.Core.Query</a></li>
--   <li><tt>Query v m</tt>.</li>
--   <li><a>Diagrams.Core.Style</a></li>
--   <li><tt>AttributeClass a</tt>, <tt>Attribute v</tt>, * <tt>Style
--   v</tt>, <tt>HasStyle</tt>.</li>
--   <li><a>Diagrams.Core.Trace</a></li>
--   <li><tt>SortedList a</tt>, * <tt>Trace v</tt>, <tt>Traced a</tt>.</li>
--   <li><a>Diagrams.Core.Transform</a></li>
--   <li><tt>u :-: v</tt>, <tt>HasLinearMap</tt>, * <tt>Transformation
--   v</tt>, <tt>Transformable t</tt>, * <tt>TransInv t</tt>.</li>
--   <li><a>Diagrams.Core.V</a></li>
--   <li><tt>V a</tt>.</li>
--   </ul>
module Diagrams.Core

-- | Many sorts of objects have an associated vector space in which they
--   "live". The type function <tt>V</tt> maps from object types to the
--   associated vector space.

-- | <tt>Point</tt> is a newtype wrapper around vectors used to represent
--   points, so we don't get them mixed up. The distinction between vectors
--   and points is important: translations affect points, but leave vectors
--   unchanged. Points are instances of the <a>AffineSpace</a> class from
--   <a>Data.AffineSpace</a>.
data Point v :: * -> *

-- | The origin of the vector space <tt>v</tt>.
origin :: AdditiveGroup v => Point v

-- | Scale a point by a scalar.
(*.) :: VectorSpace v => Scalar v -> Point v -> Point v

-- | An isomorphism between points and vectors, given a reference point.
--   This is provided for defining new lenses on points.
_relative :: AffineSpace (Point v) => Point v -> Iso' (Point v) v

-- | Get the matrix equivalent of the basis of the vector space v as a list
--   of columns.
basis :: HasLinearMap v => [v]

-- | Get the dimension of an object whose vector space is an instance of
--   <tt>HasLinearMap</tt>, e.g. transformations, paths, diagrams, etc.
dimension :: HasLinearMap (V a) => a -> Int

-- | The determinant of a <a>Transformation</a>.
determinant :: (HasLinearMap v, Num (Scalar v)) => Transformation v -> Scalar v

-- | <tt>(v1 :-: v2)</tt> is a linear map paired with its inverse.
data (:-:) u v

-- | Create an invertible linear map from two functions which are assumed
--   to be linear inverses.
(<->) :: (HasLinearMap u, HasLinearMap v) => (u -> v) -> (v -> u) -> (u :-: v)

-- | Invert a linear map.
linv :: (u :-: v) -> (v :-: u)

-- | Apply a linear map to a vector.
lapp :: (VectorSpace v, Scalar u ~ Scalar v, HasLinearMap u) => (u :-: v) -> u -> v

-- | General (affine) transformations, represented by an invertible linear
--   map, its <i>transpose</i>, and a vector representing a translation
--   component.
--   
--   By the <i>transpose</i> of a linear map we mean simply the linear map
--   corresponding to the transpose of the map's matrix representation. For
--   example, any scale is its own transpose, since scales are represented
--   by matrices with zeros everywhere except the diagonal. The transpose
--   of a rotation is the same as its inverse.
--   
--   The reason we need to keep track of transposes is because it turns out
--   that when transforming a shape according to some linear map L, the
--   shape's <i>normal vectors</i> transform according to L's inverse
--   transpose. This is exactly what we need when transforming bounding
--   functions, which are defined in terms of <i>perpendicular</i> (i.e.
--   normal) hyperplanes.
--   
--   For more general, non-invertable transformations, see
--   <tt>Diagrams.Deform</tt> (in <tt>diagrams-lib</tt>).
data Transformation v

-- | Invert a transformation.
inv :: HasLinearMap v => Transformation v -> Transformation v

-- | Get the transpose of a transformation (ignoring the translation
--   component).
transp :: Transformation v -> (v :-: v)

-- | Get the translational component of a transformation.
transl :: Transformation v -> v

-- | Drop the translational component of a transformation, leaving only the
--   linear part.
dropTransl :: AdditiveGroup v => Transformation v -> Transformation v

-- | Apply a transformation to a vector. Note that any translational
--   component of the transformation will not affect the vector, since
--   vectors are invariant under translation.
apply :: HasLinearMap v => Transformation v -> v -> v

-- | Apply a transformation to a point.
papply :: HasLinearMap v => Transformation v -> Point v -> Point v

-- | Create a general affine transformation from an invertible linear
--   transformation and its transpose. The translational component is
--   assumed to be zero.
fromLinear :: AdditiveGroup v => (v :-: v) -> (v :-: v) -> Transformation v

-- | Create a translation.
translation :: HasLinearMap v => v -> Transformation v

-- | Translate by a vector.
translate :: (Transformable t, HasLinearMap (V t)) => V t -> t -> t

-- | Translate the object by the translation that sends the origin to the
--   given point. Note that this is dual to <a>moveOriginTo</a>, i.e. we
--   should have
--   
--   <pre>
--   moveTo (origin .^+ v) === moveOriginTo (origin .^- v)
--   </pre>
--   
--   For types which are also <tt>Transformable</tt>, this is essentially
--   the same as <tt>translate</tt>, i.e.
--   
--   <pre>
--   moveTo (origin .^+ v) === translate v
--   </pre>
moveTo :: HasOrigin t => Point (V t) -> t -> t

-- | A flipped variant of <a>moveTo</a>, provided for convenience. Useful
--   when writing a function which takes a point as an argument, such as
--   when using <tt>withName</tt> and friends.
place :: HasOrigin t => t -> Point (V t) -> t

-- | Create a uniform scaling transformation.
scaling :: (HasLinearMap v, Fractional (Scalar v)) => Scalar v -> Transformation v

-- | Scale uniformly in every dimension by the given scalar.
scale :: (Transformable t, Fractional (Scalar (V t)), Eq (Scalar (V t))) => Scalar (V t) -> t -> t

-- | Compute the "average" amount of scaling performed by a transformation.
--   Satisfies the properties
--   
--   <pre>
--   avgScale (scaling k) == k
--   avgScale (t1 <a></a> t2)  == avgScale t1 * avgScale t2
--   </pre>
avgScale :: (HasLinearMap v, Floating (Scalar v)) => Transformation v -> Scalar v

-- | Type class for things <tt>t</tt> which can be transformed.
class HasLinearMap (V t) => Transformable t
transform :: Transformable t => Transformation (V t) -> t -> t

-- | <tt>TransInv</tt> is a wrapper which makes a transformable type
--   translationally invariant; the translational component of
--   transformations will no longer affect things wrapped in
--   <tt>TransInv</tt>.
newtype TransInv t
TransInv :: t -> TransInv t

-- | Atomic names. <tt>AName</tt> is just an existential wrapper around
--   things which are <a>Typeable</a>, <a>Ord</a> and <a>Show</a>.
data AName

-- | A (qualified) name is a (possibly empty) sequence of atomic names.
data Name

-- | Class for those types which can be used as names. They must support
--   <a>Typeable</a> (to facilitate extracting them from existential
--   wrappers), <a>Ord</a> (for comparison and efficient storage) and
--   <a>Show</a>.
--   
--   To make an instance of <a>IsName</a>, you need not define any methods,
--   just declare it.
--   
--   WARNING: it is not recommended to use
--   <tt>GeneralizedNewtypeDeriving</tt> in conjunction with
--   <tt>IsName</tt>, since in that case the underlying type and the
--   <tt>newtype</tt> will be considered equivalent when comparing names.
--   For example:
--   
--   <pre>
--   newtype WordN = WordN Int deriving (Show, Ord, Eq, Typeable, IsName)
--   </pre>
--   
--   is unlikely to work as intended, since <tt>(1 :: Int)</tt> and
--   <tt>(WordN 1)</tt> will be considered equal as names. Instead, use
--   
--   <pre>
--   newtype WordN = WordN Int deriving (Show, Ord, Eq, Typeable, IsName)
--   instance IsName WordN
--   </pre>
class (Typeable a, Ord a, Show a) => IsName a where toName = Name . (: []) . AName
toName :: IsName a => a -> Name

-- | Instances of <a>Qualifiable</a> are things which can be qualified by
--   prefixing them with a name.
class Qualifiable q
(|>) :: (Qualifiable q, IsName a) => a -> q -> q

-- | Convenient operator for writing qualified names with atomic components
--   of different types. Instead of writing <tt>toName a1 &lt;&gt; toName
--   a2 &lt;&gt; toName a3</tt> you can just write <tt>a1 .&gt; a2 .&gt;
--   a3</tt>.
(.>) :: (IsName a1, IsName a2) => a1 -> a2 -> Name

-- | A <a>SubMap</a> is a map associating names to subdiagrams. There can
--   be multiple associations for any given name.
newtype SubMap b v m
SubMap :: (Map Name [Subdiagram b v m]) -> SubMap b v m

-- | Construct a <a>SubMap</a> from a list of associations between names
--   and subdiagrams.
fromNames :: IsName a => [(a, Subdiagram b v m)] -> SubMap b v m

-- | Add a name/diagram association to a submap.
rememberAs :: IsName a => a -> QDiagram b v m -> SubMap b v m -> SubMap b v m

-- | Look for the given name in a name map, returning a list of subdiagrams
--   associated with that name. If no names match the given name exactly,
--   return all the subdiagrams associated with names of which the given
--   name is a suffix.
lookupSub :: IsName n => n -> SubMap b v m -> Maybe [Subdiagram b v m]

-- | Every attribute must be an instance of <tt>AttributeClass</tt>, which
--   simply guarantees <a>Typeable</a> and <a>Semigroup</a> constraints.
--   The <a>Semigroup</a> instance for an attribute determines how it will
--   combine with other attributes of the same type.
class (Typeable a, Semigroup a) => AttributeClass a

-- | An existential wrapper type to hold attributes. Some attributes are
--   simply inert/static; some are affected by transformations; and some
--   are affected by transformations and can be modified generically.
data Attribute v :: *

-- | Wrap up an attribute.
mkAttr :: AttributeClass a => a -> Attribute v

-- | Wrap up a transformable attribute.
mkTAttr :: (AttributeClass a, Transformable a, V a ~ v) => a -> Attribute v

-- | Wrap up a transformable and generic attribute.
mkGTAttr :: (AttributeClass a, Data a, Transformable a, V a ~ v) => a -> Attribute v

-- | Unwrap an unknown <a>Attribute</a> type, performing a dynamic (but
--   safe) check on the type of the result. If the required type matches
--   the type of the attribute, the attribute value is returned wrapped in
--   <tt>Just</tt>; if the types do not match, <tt>Nothing</tt> is
--   returned.
unwrapAttr :: AttributeClass a => Attribute v -> Maybe a

-- | A <tt>Style</tt> is a heterogeneous collection of attributes,
--   containing at most one attribute of any given type.
data Style v

-- | Type class for things which have a style.
class HasStyle a
applyStyle :: HasStyle a => Style (V a) -> a -> a

-- | Extract an attribute from a style of a particular type. If the style
--   contains an attribute of the requested type, it will be returned
--   wrapped in <tt>Just</tt>; otherwise, <tt>Nothing</tt> is returned.
getAttr :: AttributeClass a => Style v -> Maybe a

-- | Add a new attribute to a style that does not already contain an
--   attribute of this type, or combine it on the left with an existing
--   attribute.
combineAttr :: AttributeClass a => a -> Style v -> Style v

-- | Apply an attribute to an instance of <a>HasStyle</a> (such as a
--   diagram or a style). If the object already has an attribute of the
--   same type, the new attribute is combined on the left with the existing
--   attribute, according to their semigroup structure.
applyAttr :: (AttributeClass a, HasStyle d) => a -> d -> d

-- | Apply a transformable attribute to an instance of <a>HasStyle</a>
--   (such as a diagram or a style). If the object already has an attribute
--   of the same type, the new attribute is combined on the left with the
--   existing attribute, according to their semigroup structure.
applyTAttr :: (AttributeClass a, Transformable a, V a ~ V d, HasStyle d) => a -> d -> d
applyGTAttr :: (AttributeClass a, Data a, Transformable a, V a ~ V d, HasStyle d) => a -> d -> d

-- | Every diagram comes equipped with an <i>envelope</i>. What is an
--   envelope?
--   
--   Consider first the idea of a <i>bounding box</i>. A bounding box
--   expresses the distance to a bounding plane in every direction parallel
--   to an axis. That is, a bounding box can be thought of as the
--   intersection of a collection of half-planes, two perpendicular to each
--   axis.
--   
--   More generally, the intersection of half-planes in <i>every</i>
--   direction would give a tight "bounding region", or convex hull.
--   However, representing such a thing intensionally would be impossible;
--   hence bounding boxes are often used as an approximation.
--   
--   An envelope is an <i>extensional</i> representation of such a
--   "bounding region". Instead of storing some sort of direct
--   representation, we store a <i>function</i> which takes a direction as
--   input and gives a distance to a bounding half-plane as output. The
--   important point is that envelopes can be composed, and transformed by
--   any affine transformation.
--   
--   Formally, given a vector <tt>v</tt>, the envelope computes a scalar
--   <tt>s</tt> such that
--   
--   <ul>
--   <li>for every point <tt>u</tt> inside the diagram, if the projection
--   of <tt>(u - origin)</tt> onto <tt>v</tt> is <tt>s' *^ v</tt>, then
--   <tt>s' &lt;= s</tt>.</li>
--   <li><tt>s</tt> is the smallest such scalar.</li>
--   </ul>
--   
--   There is also a special "empty envelope".
--   
--   The idea for envelopes came from Sebastian Setzer; see
--   <a>http://byorgey.wordpress.com/2009/10/28/collecting-attributes/#comment-2030</a>.
--   See also Brent Yorgey, <i>Monoids: Theme and Variations</i>, published
--   in the 2012 Haskell Symposium:
--   <a>http://www.cis.upenn.edu/~byorgey/pub/monoid-pearl.pdf</a>; video:
--   <a>http://www.youtube.com/watch?v=X-8NCkD2vOw</a>.
newtype Envelope v
Envelope :: (Option (v -> Max (Scalar v))) -> Envelope v
appEnvelope :: Envelope v -> Maybe (v -> Scalar v)
onEnvelope :: ((v -> Scalar v) -> (v -> Scalar v)) -> Envelope v -> Envelope v
mkEnvelope :: (v -> Scalar v) -> Envelope v

-- | <tt>Enveloped</tt> abstracts over things which have an envelope.
class (InnerSpace (V a), OrderedField (Scalar (V a))) => Enveloped a
getEnvelope :: Enveloped a => a -> Envelope (V a)

-- | Compute the vector from the local origin to a separating hyperplane in
--   the given direction, or <tt>Nothing</tt> for the empty envelope.
envelopeVMay :: Enveloped a => V a -> a -> Maybe (V a)

-- | Compute the vector from the local origin to a separating hyperplane in
--   the given direction. Returns the zero vector for the empty envelope.
envelopeV :: Enveloped a => V a -> a -> V a

-- | Compute the point on a separating hyperplane in the given direction,
--   or <tt>Nothing</tt> for the empty envelope.
envelopePMay :: Enveloped a => V a -> a -> Maybe (Point (V a))

-- | Compute the point on a separating hyperplane in the given direction.
--   Returns the origin for the empty envelope.
envelopeP :: Enveloped a => V a -> a -> Point (V a)

-- | Compute the diameter of a enveloped object along a particular vector.
--   Returns zero for the empty envelope.
diameter :: Enveloped a => V a -> a -> Scalar (V a)

-- | Compute the "radius" (1/2 the diameter) of an enveloped object along a
--   particular vector.
radius :: Enveloped a => V a -> a -> Scalar (V a)

-- | Every diagram comes equipped with a <i>trace</i>. Intuitively, the
--   trace for a diagram is like a raytracer: given a line (represented as
--   a base point and a direction vector), the trace computes a sorted list
--   of signed distances from the base point to all intersections of the
--   line with the boundary of the diagram.
--   
--   Note that the outputs are not absolute distances, but multipliers
--   relative to the input vector. That is, if the base point is <tt>p</tt>
--   and direction vector is <tt>v</tt>, and one of the output scalars is
--   <tt>s</tt>, then there is an intersection at the point <tt>p .+^ (s *^
--   v)</tt>.
--   
newtype Trace v
Trace :: (Point v -> v -> SortedList (Scalar v)) -> Trace v
appTrace :: Trace v -> Point v -> v -> SortedList (Scalar v)

-- | A newtype wrapper around a list which maintains the invariant that the
--   list is sorted. The constructor is not exported; use the smart
--   constructor <a>mkSortedList</a> (which sorts the given list) instead.
data SortedList a

-- | A smart constructor for the <a>SortedList</a> type, which sorts the
--   input to ensure the <a>SortedList</a> invariant.
mkSortedList :: Ord a => [a] -> SortedList a

-- | Project the (guaranteed sorted) list out of a <a>SortedList</a>
--   wrapper.
getSortedList :: SortedList a -> [a]
mkTrace :: (Point v -> v -> SortedList (Scalar v)) -> Trace v

-- | <tt>Traced</tt> abstracts over things which have a trace.
class (Ord (Scalar (V a)), VectorSpace (V a)) => Traced a
getTrace :: Traced a => a -> Trace (V a)

-- | Compute the vector from the given point <tt>p</tt> to the "smallest"
--   boundary intersection along the given vector <tt>v</tt>. The
--   "smallest" boundary intersection is defined as the one given by <tt>p
--   .+^ (s *^ v)</tt> for the smallest (most negative) value of
--   <tt>s</tt>. Return <tt>Nothing</tt> if there is no intersection. See
--   also <a>traceP</a>.
--   
--   See also <a>rayTraceV</a> which uses the smallest <i>positive</i>
--   intersection, which is often more intuitive behavior.
--   
traceV :: Traced a => Point (V a) -> V a -> a -> Maybe (V a)

-- | Compute the "smallest" boundary point along the line determined by the
--   given point <tt>p</tt> and vector <tt>v</tt>. The "smallest" boundary
--   point is defined as the one given by <tt>p .+^ (s *^ v)</tt> for the
--   smallest (most negative) value of <tt>s</tt>. Return <tt>Nothing</tt>
--   if there is no such boundary point. See also <a>traceV</a>.
--   
--   See also <a>rayTraceP</a> which uses the smallest <i>positive</i>
--   intersection, which is often more intuitive behavior.
--   
traceP :: Traced a => Point (V a) -> V a -> a -> Maybe (Point (V a))

-- | Like <a>traceV</a>, but computes a vector to the "largest" boundary
--   point instead of the smallest. (Note, however, the "largest" boundary
--   point may still be in the opposite direction from the given vector, if
--   all the boundary points are, as in the third example shown below.)
--   
maxTraceV :: Traced a => Point (V a) -> V a -> a -> Maybe (V a)

-- | Like <a>traceP</a>, but computes the "largest" boundary point instead
--   of the smallest. (Note, however, the "largest" boundary point may
--   still be in the opposite direction from the given vector, if all the
--   boundary points are.)
--   
maxTraceP :: Traced a => Point (V a) -> V a -> a -> Maybe (Point (V a))

-- | Compute the vector from the given point to the closest boundary point
--   of the given object in the given direction, or <tt>Nothing</tt> if
--   there is no such boundary point (as in the third example below). Note
--   that unlike <a>traceV</a>, only <i>positive</i> boundary points are
--   considered, <i>i.e.</i> boundary points corresponding to a positive
--   scalar multiple of the direction vector. This is intuitively the
--   "usual" behavior of a raytracer, which only considers intersections
--   "in front of" the camera. Compare the second example diagram below
--   with the second example shown for <a>traceV</a>.
--   
rayTraceV :: (Traced a, Num (Scalar (V a))) => Point (V a) -> V a -> a -> Maybe (V a)

-- | Compute the boundary point on an object which is closest to the given
--   base point in the given direction, or <tt>Nothing</tt> if there is no
--   such boundary point. Note that unlike <a>traceP</a>, only
--   <i>positive</i> boundary points are considered, <i>i.e.</i> boundary
--   points corresponding to a positive scalar multiple of the direction
--   vector. This is intuitively the "usual" behavior of a raytracer, which
--   only considers intersection points "in front of" the camera.
--   
rayTraceP :: (Traced a, Num (Scalar (V a))) => Point (V a) -> V a -> a -> Maybe (Point (V a))

-- | Like <a>rayTraceV</a>, but computes a vector to the "largest" boundary
--   point instead of the smallest. Considers only <i>positive</i> boundary
--   points.
--   
maxRayTraceV :: (Traced a, Num (Scalar (V a))) => Point (V a) -> V a -> a -> Maybe (V a)

-- | Like <a>rayTraceP</a>, but computes the "largest" boundary point
--   instead of the smallest. Considers only <i>positive</i> boundary
--   points.
--   
maxRayTraceP :: (Traced a, Num (Scalar (V a))) => Point (V a) -> V a -> a -> Maybe (Point (V a))

-- | Class of types which have an intrinsic notion of a "local origin",
--   i.e. things which are not invariant under translation, and which allow
--   the origin to be moved.
--   
--   One might wonder why not just use <tt>Transformable</tt> instead of
--   having a separate class for <a>HasOrigin</a>; indeed, for types which
--   are instances of both we should have the identity
--   
--   <pre>
--   moveOriginTo (origin .^+ v) === translate (negateV v)
--   </pre>
--   
--   The reason is that some things (e.g. vectors, <tt>Trail</tt>s) are
--   transformable but are translationally invariant, i.e. have no origin.
class VectorSpace (V t) => HasOrigin t
moveOriginTo :: HasOrigin t => Point (V t) -> t -> t

-- | Move the local origin by a relative vector.
moveOriginBy :: HasOrigin t => V t -> t -> t

-- | Class of things which can be placed "next to" other things, for some
--   appropriate notion of "next to".
class Juxtaposable a
juxtapose :: Juxtaposable a => V a -> a -> a -> a

-- | Default implementation of <a>juxtapose</a> for things which are
--   instances of <a>Enveloped</a> and <a>HasOrigin</a>. If either envelope
--   is empty, the second object is returned unchanged.
juxtaposeDefault :: (Enveloped a, HasOrigin a) => V a -> a -> a -> a

-- | A query is a function that maps points in a vector space to values in
--   some monoid. Queries naturally form a monoid, with two queries being
--   combined pointwise.
--   
--   The idea for annotating diagrams with monoidal queries came from the
--   graphics-drawingcombinators package,
--   <a>http://hackage.haskell.org/package/graphics-drawingcombinators</a>.
newtype Query v m
Query :: (Point v -> m) -> Query v m
runQuery :: Query v m -> Point v -> m

-- | A value of type <tt>Prim b v</tt> is an opaque (existentially
--   quantified) primitive which backend <tt>b</tt> knows how to render in
--   vector space <tt>v</tt>.
data Prim b v
Prim :: p -> Prim b (V p)

-- | The fundamental diagram type. The type variables are as follows:
--   
--   <ul>
--   <li><tt>b</tt> represents the backend, such as <tt>SVG</tt> or
--   <tt>Cairo</tt>. Note that each backend also exports a type synonym
--   <tt>B</tt> for itself, so the type variable <tt>b</tt> may also
--   typically be instantiated by <tt>B</tt>, meaning "use whatever backend
--   is in scope".</li>
--   <li><tt>v</tt> represents the vector space of the diagram. Typical
--   instantiations include <tt>R2</tt> (for a two-dimensional diagram) or
--   <tt>R3</tt> (for a three-dimensional diagram).</li>
--   <li><tt>m</tt> is the monoidal type of "query annotations": each point
--   in the diagram has a value of type <tt>m</tt> associated to it, and
--   these values are combined according to the <a>Monoid</a> instance for
--   <tt>m</tt>. Most often, <tt>m</tt> is simply instantiated to
--   <a>Any</a>, associating a simple <tt>Bool</tt> value to each point
--   indicating whether the point is inside the diagram; <a>Diagram</a> is
--   a synonym for <tt>QDiagram</tt> with <tt>m</tt> thus instantiated to
--   <tt>Any</tt>.</li>
--   </ul>
--   
--   Diagrams can be combined via their <a>Monoid</a> instance, transformed
--   via their <a>Transformable</a> instance, and assigned attributes via
--   their <a>HasStyle</a> instance.
--   
--   Note that the <tt>Q</tt> in <tt>QDiagram</tt> stands for "Queriable",
--   as distinguished from <a>Diagram</a>, where <tt>m</tt> is fixed to
--   <tt>Any</tt>. This is not really a very good name, but it's probably
--   not worth changing it at this point.
data QDiagram b v m

-- | <tt>Diagram b v</tt> is a synonym for <tt><a>QDiagram</a> b v
--   <a>Any</a></tt>. That is, the default sort of diagram is one where
--   querying at a point simply tells you whether the diagram contains that
--   point or not. Transforming a default diagram into one with a more
--   interesting query can be done via the <a>Functor</a> instance of
--   <tt><a>QDiagram</a> b</tt> or the <a>value</a> function.
type Diagram b v = QDiagram b v Any

-- | Create a diagram from a single primitive, along with an envelope,
--   trace, subdiagram map, and query function.
mkQD :: Prim b v -> Envelope v -> Trace v -> SubMap b v m -> Query v m -> QDiagram b v m

-- | Create a "point diagram", which has no content, no trace, an empty
--   query, and a point envelope.
pointDiagram :: (Fractional (Scalar v), InnerSpace v) => Point v -> QDiagram b v m

-- | Get the envelope of a diagram.
envelope :: (OrderedField (Scalar v), InnerSpace v, HasLinearMap v, Monoid' m) => Lens' (QDiagram b v m) (Envelope v)

-- | Get the trace of a diagram.
trace :: (InnerSpace v, HasLinearMap v, OrderedField (Scalar v), Semigroup m) => Lens' (QDiagram b v m) (Trace v)

-- | Get the subdiagram map (<i>i.e.</i> an association from names to
--   subdiagrams) of a diagram.
subMap :: (HasLinearMap v, InnerSpace v, Semigroup m, OrderedField (Scalar v)) => Lens' (QDiagram b v m) (SubMap b v m)

-- | Get a list of names of subdiagrams and their locations.
names :: (HasLinearMap v, InnerSpace v, Semigroup m, OrderedField (Scalar v)) => QDiagram b v m -> [(Name, [Point v])]

-- | Get the query function associated with a diagram.
query :: Monoid m => QDiagram b v m -> Query v m

-- | Sample a diagram's query function at a given point.
sample :: Monoid m => QDiagram b v m -> Point v -> m

-- | Set the query value for <a>True</a> points in a diagram (<i>i.e.</i>
--   points "inside" the diagram); <a>False</a> points will be set to
--   <a>mempty</a>.
value :: Monoid m => m -> QDiagram b v Any -> QDiagram b v m

-- | Reset the query values of a diagram to <tt>True</tt>/<tt>False</tt>:
--   any values equal to <a>mempty</a> are set to <a>False</a>; any other
--   values are set to <a>True</a>.
resetValue :: (Eq m, Monoid m) => QDiagram b v m -> QDiagram b v Any

-- | Set all the query values of a diagram to <a>False</a>.
clearValue :: QDiagram b v m -> QDiagram b v Any

-- | Attach an atomic name to a certain subdiagram, computed from the given
--   diagram /with the mapping from name to subdiagram included/. The
--   upshot of this knot-tying is that if <tt>d' = d # named x</tt>, then
--   <tt>lookupName x d' == Just d'</tt> (instead of <tt>Just d</tt>).
nameSub :: (IsName n, HasLinearMap v, InnerSpace v, OrderedField (Scalar v), Semigroup m) => (QDiagram b v m -> Subdiagram b v m) -> n -> QDiagram b v m -> QDiagram b v m

-- | Given a name and a diagram transformation indexed by a subdiagram,
--   perform the transformation using the most recent subdiagram associated
--   with (some qualification of) the name, or perform the identity
--   transformation if the name does not exist.
withName :: (IsName n, HasLinearMap v, InnerSpace v, Semigroup m, OrderedField (Scalar v)) => n -> (Subdiagram b v m -> QDiagram b v m -> QDiagram b v m) -> QDiagram b v m -> QDiagram b v m

-- | Given a name and a diagram transformation indexed by a list of
--   subdiagrams, perform the transformation using the collection of all
--   such subdiagrams associated with (some qualification of) the given
--   name.
withNameAll :: (IsName n, HasLinearMap v, InnerSpace v, Semigroup m, OrderedField (Scalar v)) => n -> ([Subdiagram b v m] -> QDiagram b v m -> QDiagram b v m) -> QDiagram b v m -> QDiagram b v m

-- | Given a list of names and a diagram transformation indexed by a list
--   of subdiagrams, perform the transformation using the list of most
--   recent subdiagrams associated with (some qualification of) each name.
--   Do nothing (the identity transformation) if any of the names do not
--   exist.
withNames :: (IsName n, HasLinearMap v, InnerSpace v, Semigroup m, OrderedField (Scalar v)) => [n] -> ([Subdiagram b v m] -> QDiagram b v m -> QDiagram b v m) -> QDiagram b v m -> QDiagram b v m

-- | "Localize" a diagram by hiding all the names, so they are no longer
--   visible to the outside.
localize :: (HasLinearMap v, InnerSpace v, OrderedField (Scalar v), Semigroup m) => QDiagram b v m -> QDiagram b v m

-- | Make a diagram into a hyperlink. Note that only some backends will
--   honor hyperlink annotations.
href :: (HasLinearMap v, InnerSpace v, OrderedField (Scalar v), Semigroup m) => String -> QDiagram b v m -> QDiagram b v m

-- | Replace the envelope of a diagram.
setEnvelope :: (OrderedField (Scalar v), InnerSpace v, HasLinearMap v, Monoid' m) => Envelope v -> QDiagram b v m -> QDiagram b v m

-- | Replace the trace of a diagram.
setTrace :: (OrderedField (Scalar v), InnerSpace v, HasLinearMap v, Semigroup m) => Trace v -> QDiagram b v m -> QDiagram b v m

-- | A convenient synonym for <a>mappend</a> on diagrams, designed to be
--   used infix (to help remember which diagram goes on top of which when
--   combining them, namely, the first on top of the second).
atop :: (HasLinearMap v, OrderedField (Scalar v), InnerSpace v, Semigroup m) => QDiagram b v m -> QDiagram b v m -> QDiagram b v m

-- | A <tt>Subdiagram</tt> represents a diagram embedded within the context
--   of a larger diagram. Essentially, it consists of a diagram paired with
--   any accumulated information from the larger context (transformations,
--   attributes, etc.).
data Subdiagram b v m
Subdiagram :: (QDiagram b v m) -> (DownAnnots v) -> Subdiagram b v m

-- | Turn a diagram into a subdiagram with no accumulated context.
mkSubdiagram :: QDiagram b v m -> Subdiagram b v m

-- | Turn a subdiagram into a normal diagram, including the enclosing
--   context. Concretely, a subdiagram is a pair of (1) a diagram and (2) a
--   "context" consisting of an extra transformation and attributes.
--   <tt>getSub</tt> simply applies the transformation and attributes to
--   the diagram to get the corresponding "top-level" diagram.
getSub :: (HasLinearMap v, InnerSpace v, Floating (Scalar v), Ord (Scalar v), Semigroup m) => Subdiagram b v m -> QDiagram b v m

-- | Extract the "raw" content of a subdiagram, by throwing away the
--   context.
rawSub :: Subdiagram b v m -> QDiagram b v m

-- | Get the location of a subdiagram; that is, the location of its local
--   origin <i>with respect to</i> the vector space of its parent diagram.
--   In other words, the point where its local origin "ended up".
location :: HasLinearMap v => Subdiagram b v m -> Point v

-- | Create a "point subdiagram", that is, a <a>pointDiagram</a> (with no
--   content and a point envelope) treated as a subdiagram with local
--   origin at the given point. Note this is not the same as
--   <tt>mkSubdiagram . pointDiagram</tt>, which would result in a
--   subdiagram with local origin at the parent origin, rather than at the
--   given point.
subPoint :: (HasLinearMap v, InnerSpace v, OrderedField (Scalar v), Semigroup m) => Point v -> Subdiagram b v m

-- | Type of measurement units for attributes.
data Measure v
Output :: (Scalar v) -> Measure v
Normalized :: (Scalar v) -> Measure v
Local :: (Scalar v) -> Measure v
Global :: (Scalar v) -> Measure v
MinM :: (Measure v) -> (Measure v) -> Measure v
MaxM :: (Measure v) -> (Measure v) -> Measure v
ZeroM :: Measure v
NegateM :: (Measure v) -> Measure v
PlusM :: (Measure v) -> (Measure v) -> Measure v
ScaleM :: (Scalar v) -> (Measure v) -> Measure v

-- | Retrieve the <a>Output</a> value of a 'Measure v' or throw an
--   exception. Only <tt>Ouput</tt> measures should be left in the
--   <a>RTree</a> passed to the backend.
fromOutput :: Measure v -> Scalar v

-- | Convert an aribrary <a>Measure</a> to <a>Output</a> units.
toOutput :: (Data v, Data (Scalar v), Num (Scalar v), Ord (Scalar v), Fractional (Scalar v)) => Scalar v -> Scalar v -> Measure v -> Measure v

-- | Compute the smaller of two <a>Measure</a>s. Useful for setting upper
--   bounds.
atMost :: Measure v -> Measure v -> Measure v

-- | Compute the larger of two <a>Measure</a>s. Useful for setting lower
--   bounds.
atLeast :: Measure v -> Measure v -> Measure v

-- | Abstract diagrams are rendered to particular formats by
--   <i>backends</i>. Each backend/vector space combination must be an
--   instance of the <a>Backend</a> class.
--   
--   A minimal complete definition consists of <a>Render</a>,
--   <a>Result</a>, <a>Options</a>, and <a>renderRTree</a>. However, most
--   backends will want to implement <a>adjustDia</a> as well; the default
--   definition does nothing. Some useful standard definitions are provided
--   in the <tt>Diagrams.TwoD.Adjust</tt> module from the
--   <tt>diagrams-lib</tt> package.
class HasLinearMap v => Backend b v where data family Render b v :: * type family Result b v :: * data family Options b v :: * adjustDia _ o d = (o, mempty, d)
adjustDia :: (Backend b v, Monoid' m, Num (Scalar v)) => b -> Options b v -> QDiagram b v m -> (Options b v, Transformation v, QDiagram b v m)
renderRTree :: Backend b v => b -> Options b v -> RTree b v Annotation -> Result b v

-- | The Renderable type class connects backends to primitives which they
--   know how to render.
class Transformable t => Renderable t b
render :: Renderable t b => b -> t -> Render b (V t)

-- | Render a diagram.
renderDia :: (Backend b v, InnerSpace v, Data v, OrderedField (Scalar v), Data (Scalar v), Monoid' m) => b -> Options b v -> QDiagram b v m -> Result b v

-- | Render a diagram, returning also the transformation which was used to
--   convert the diagram from its ("global") coordinate system into the
--   output coordinate system. The inverse of this transformation can be
--   used, for example, to convert output/screen coordinates back into
--   diagram coordinates. See also <a>adjustDia</a>.
renderDiaT :: (Backend b v, HasLinearMap v, InnerSpace v, Data v, OrderedField (Scalar v), Data (Scalar v), Monoid' m) => b -> Options b v -> QDiagram b v m -> (Transformation v, Result b v)

-- | A null backend which does no actual rendering. It is provided mainly
--   for convenience in situations where you must give a diagram a
--   concrete, monomorphic type, but don't actually care which one. See
--   <a>D</a> for more explanation and examples.
--   
--   It is courteous, when defining a new primitive <tt>P</tt>, to make an
--   instance
--   
--   <pre>
--   instance Renderable P NullBackend where
--     render _ _ = mempty
--   </pre>
--   
--   This ensures that the trick with <a>D</a> annotations can be used for
--   diagrams containing your primitive.
data NullBackend

-- | The <tt>D</tt> type is provided for convenience in situations where
--   you must give a diagram a concrete, monomorphic type, but don't care
--   which one. Such situations arise when you pass a diagram to a function
--   which is polymorphic in its input but monomorphic in its output, such
--   as <tt>width</tt>, <tt>height</tt>, <tt>phantom</tt>, or <a>names</a>.
--   Such functions compute some property of the diagram, or use it to
--   accomplish some other purpose, but do not result in the diagram being
--   rendered. If the diagram does not have a monomorphic type, GHC
--   complains that it cannot determine the diagram's type.
--   
--   For example, here is the error we get if we try to compute the width
--   of an image (this example requires <tt>diagrams-lib</tt>):
--   
--   <pre>
--   ghci&gt; width (image "foo.png" 200 200)
--   &lt;interactive&gt;:8:8:
--       No instance for (Renderable Diagrams.TwoD.Image.Image b0)
--         arising from a use of <tt>image</tt>
--       Possible fix:
--         add an instance declaration for
--         (Renderable Diagrams.TwoD.Image.Image b0)
--       In the first argument of <tt>width</tt>, namely
--         `(image "foo.png" 200 200)'
--       In the expression: width (image "foo.png" 200 200)
--       In an equation for <tt>it</tt>: it = width (image "foo.png" 200 200)
--   </pre>
--   
--   GHC complains that there is no instance for <tt>Renderable Image
--   b0</tt>; what is really going on is that it does not have enough
--   information to decide what backend to use (hence the uninstantiated
--   <tt>b0</tt>). This is annoying because <i>we</i> know that the choice
--   of backend cannot possibly affect the width of the image (it's 200!
--   it's right there in the code!); <i>but</i> there is no way for GHC to
--   know that.
--   
--   The solution is to annotate the call to <tt>image</tt> with the type
--   <tt><a>D</a> <tt>R2</tt></tt>, like so:
--   
--   <pre>
--   ghci&gt; width (image "foo.png" 200 200 :: D R2)
--   200.00000000000006
--   </pre>
--   
--   (It turns out the width wasn't 200 after all...)
--   
--   As another example, here is the error we get if we try to compute the
--   width of a radius-1 circle:
--   
--   <pre>
--   ghci&gt; width (circle 1)
--   &lt;interactive&gt;:4:1:
--       Couldn't match type `V a0' with <tt>R2</tt>
--       In the expression: width (circle 1)
--       In an equation for <tt>it</tt>: it = width (circle 1)
--   </pre>
--   
--   There's even more ambiguity here. Whereas <tt>image</tt> always
--   returns a <a>Diagram</a>, the <tt>circle</tt> function can produce any
--   <tt>PathLike</tt> type, and the <tt>width</tt> function can consume
--   any <a>Enveloped</a> type, so GHC has no idea what type to pick to go
--   in the middle. However, the solution is the same:
--   
--   <pre>
--   ghci&gt; width (circle 1 :: D R2)
--   1.9999999999999998
--   </pre>
type D v = Diagram NullBackend v

-- | <a>HasLinearMap</a> is a poor man's class constraint synonym, just to
--   help shorten some of the ridiculously long constraint sets.
class (HasBasis v, HasTrie (Basis v), VectorSpace v) => HasLinearMap v

-- | When dealing with envelopes we often want scalars to be an ordered
--   field (i.e. support all four arithmetic operations and be totally
--   ordered) so we introduce this class as a convenient shorthand.
class (Fractional s, Floating s, Ord s, AdditiveGroup s) => OrderedField s

-- | The <tt>Monoid'</tt> class is a synonym for things which are instances
--   of both <a>Semigroup</a> and <a>Monoid</a>. Ideally, the <a>Monoid</a>
--   class itself will eventually include a <a>Semigroup</a> superclass and
--   we can get rid of this.
class (Semigroup m, Monoid m) => Monoid' m
