-- 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 0.7.0.1


-- | 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


-- | 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.
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

-- | 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 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)

-- | <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
unTransInv :: TransInv t -> 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 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>.
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 (TransInv a)
instance [overlap ok] Qualifiable Name
instance [overlap ok] IsName Name
instance [overlap ok] Show 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)


-- | 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
--   affected by transformations and some are not.
data Attribute v :: *
Attribute :: a -> Attribute v
TAttribute :: 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

-- | 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

-- | 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

-- | 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

-- | 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 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

-- | 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), the trace computes the distance from
--   the base point along the line to the first intersection with the
--   diagram. The distance can be negative if the intersection is in the
--   opposite direction from the base point, or infinite if the ray never
--   intersects the diagram. Note: to obtain the distance to the
--   <i>furthest</i> intersection instead of the <i>closest</i>, just
--   negate the direction vector and then negate the result.
--   
--   Note that the output should actually be interpreted not as an absolute
--   distance, but as a multiplier relative to the input vector. That is,
--   if the input vector is <tt>v</tt> and the returned scalar is
--   <tt>s</tt>, the distance from the base point to the intersection is
--   given by <tt>s * magnitude v</tt>.
newtype Trace v
Trace :: (Point v -> v -> PosInf (Scalar v)) -> Trace v
appTrace :: Trace v -> Point v -> v -> PosInf (Scalar v)
inTrace :: ((Point v -> v -> PosInf (Scalar v)) -> (Point v -> v -> PosInf (Scalar v))) -> Trace v -> Trace v
mkTrace :: (Point v -> v -> PosInf (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 to the boundary of the given
--   object in the given direction, or <tt>Nothing</tt> if there is no
--   intersection.
traceV :: Traced a => Point (V a) -> V a -> a -> Maybe (V a)

-- | Given a base point and direction, compute the closest point on the
--   boundary of the given object, or <tt>Nothing</tt> if there is no
--   intersection in the given direction.
traceP :: Traced a => Point (V a) -> V a -> a -> Maybe (Point (V a))

-- | Like <a>traceV</a>, but computes a vector to the *furthest* point on
--   the boundary instead of the closest.
maxTraceV :: Traced a => Point (V a) -> V a -> a -> Maybe (V a)

-- | Like <a>traceP</a>, but computes the *furthest* point on the boundary
--   instead of the closest.
maxTraceP :: Traced 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)


-- | <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
unEnvelope :: Envelope v -> Option (v -> Max (Scalar v))
inEnvelope :: (Option (v -> Max (Scalar v)) -> Option (v -> Max (Scalar v))) -> Envelope 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 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)


-- | 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 (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

-- | 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>transformations (split at the innermost freeze): see
--   <a>Diagrams.Core.Transform</a></li>
--   <li>styles (see <a>Diagrams.Core.Style</a>)</li>
--   <li>names (see <a>Diagrams.Core.Names</a>)</li>
--   </ul>
type DownAnnots v = (Split (Transformation v) :+: Style v) ::: (Name ::: ())

-- | The fundamental diagram type is represented by trees of primitives
--   with various monoidal annotations. The <tt>Q</tt> in <tt>QDiagram</tt>
--   stands for "Queriable", as distinguished from <a>Diagram</a>, a
--   synonym for <tt>QDiagram</tt> with the query type specialized to
--   <a>Any</a>.
newtype QDiagram b v m
QD :: DUALTree (DownAnnots v) (UpAnnots b v m) () (Prim b v) -> QDiagram b v m
unQD :: QDiagram b v m -> DUALTree (DownAnnots v) (UpAnnots b v m) () (Prim b v)

-- | 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

-- | 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

-- | Extract a list of primitives from a diagram, together with their
--   associated transformations and styles.
prims :: HasLinearMap v => QDiagram b v m -> [(Prim b v, (Split (Transformation v), Style v))]

-- | Get the envelope of a diagram.
envelope :: Ord (Scalar v) => QDiagram b v m -> Envelope v

-- | Get the trace of a diagram.
trace :: (Ord (Scalar v), VectorSpace v, HasLinearMap v) => QDiagram b v m -> Trace v

-- | Get the subdiagram map (<i>i.e.</i> an association from names to
--   subdiagrams) of a diagram.
subMap :: QDiagram b v m -> SubMap b v m

-- | Get a list of names of subdiagrams and their locations.
names :: HasLinearMap 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.
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 => 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 => 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 => [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

-- | By default, diagram attributes are not affected by transformations.
--   This means, for example, that <tt>lw 0.01 circle</tt> and <tt>scale 2
--   (lw 0.01 circle)</tt> will be drawn with lines of the <i>same</i>
--   width, and <tt>scaleY 3 circle</tt> will be an ellipse drawn with a
--   uniform line. Once a diagram is frozen, however, transformations do
--   affect attributes, so, for example, <tt>scale 2 (freeze (lw 0.01
--   circle))</tt> will be drawn with a line twice as thick as <tt>lw 0.01
--   circle</tt>, and <tt>scaleY 3 (freeze circle)</tt> will be drawn with
--   a "stretched", variable-width line.
--   
--   Another way of thinking about it is that pre-<tt>freeze</tt>, we are
--   transforming the "abstract idea" of a diagram, and the transformed
--   version is then drawn; when doing a <tt>freeze</tt>, we produce a
--   concrete drawing of the diagram, and it is this visual representation
--   itself which is acted upon by subsequent transformations.
freeze :: (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

-- | 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)

-- | A type class for primitive things which know how to handle being
--   transformed by both a normal transformation and a "frozen"
--   transformation. The default implementation simply applies both. At the
--   moment, <tt>ScaleInv</tt> is the only type with a non-default instance
--   of <a>IsPrim</a>.
class Transformable p => IsPrim p where transformWithFreeze t1 t2 = transform (t1 <> t2)
transformWithFreeze :: IsPrim p => Transformation (V p) -> Transformation (V p) -> p -> p

-- | The null primitive, which every backend can render by doing nothing.
nullPrim :: (HasLinearMap v, Monoid (Render b v)) => Prim b 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 the three associated types and implementations for
--   <a>withStyle</a> and <a>doRender</a>.
class (HasLinearMap v, Monoid (Render b v)) => Backend b v where data family Render b v :: * type family Result b v :: * data family Options b v :: * adjustDia _ o d = (o, d) renderDia b opts d = doRender b opts' . mconcat . map renderOne . prims $ d' where (opts', d') = adjustDia b opts d renderOne :: (Prim b v, (Split (Transformation v), Style v)) -> Render b v renderOne (p, (M t, s)) = withStyle b s mempty (render b (transform t p)) renderOne (p, (t1 :| t2, s)) = withStyle b s t1 (render b (transformWithFreeze t1 t2 p))
withStyle :: Backend b v => b -> Style v -> Transformation v -> Render b v -> Render b v
doRender :: Backend b v => b -> Options b v -> Render b v -> Result b v
adjustDia :: (Backend b v, Monoid' m) => b -> Options b v -> QDiagram b v m -> (Options b v, QDiagram b v m)
renderDia :: (Backend b v, InnerSpace v, OrderedField (Scalar v), Monoid' m) => b -> Options b v -> QDiagram b v m -> Result b v

-- | A class for backends which support rendering multiple diagrams, e.g.
--   to a multi-page pdf or something similar.
class Backend b v => MultiBackend b v
renderDias :: (MultiBackend b v, InnerSpace v, OrderedField (Scalar v), Monoid' m) => b -> Options b v -> [QDiagram b v m] -> 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 `image'
--       Possible fix:
--         add an instance declaration for
--         (Renderable Diagrams.TwoD.Image.Image b0)
--       In the first argument of `width', namely
--         `(image "foo.png" 200 200)'
--       In the expression: width (image "foo.png" 200 200)
--       In an equation for `it': 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 `R2'
--       In the expression: width (circle 1)
--       In an equation for `it': 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 Typeable3 QDiagram
instance HasLinearMap v => Backend NullBackend v
instance Monoid (Render NullBackend v)
instance (HasLinearMap v, Monoid (Render b v)) => Renderable (NullPrim v) b
instance HasLinearMap v => Transformable (NullPrim v)
instance HasLinearMap v => IsPrim (NullPrim v)
instance HasLinearMap v => Renderable (Prim b v) b
instance HasLinearMap v => Transformable (Prim b v)
instance HasLinearMap v => IsPrim (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 Newtype (SubMap b v m) (Map Name [Subdiagram 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 (Ord (Scalar v), VectorSpace v, HasLinearMap v) => Traced (Subdiagram b v m)
instance (OrderedField (Scalar v), InnerSpace v, HasLinearMap v) => 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)) => Traced (QDiagram b v m)
instance (HasLinearMap v, InnerSpace v, OrderedField (Scalar v)) => Enveloped (QDiagram b v m)
instance (HasLinearMap v, InnerSpace v, OrderedField (Scalar v), Semigroup 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 Newtype (QDiagram b v m) (DUALTree (DownAnnots v) (UpAnnots b v m) () (Prim b 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 <a>Diagrams.Prelude</a>) 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.
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

-- | <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.
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

-- | 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

-- | 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
unTransInv :: TransInv t -> 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>.
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
--   affected by transformations and some are not.
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

-- | 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

-- | 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>.
data Envelope v
inEnvelope :: (Option (v -> Max (Scalar v)) -> Option (v -> Max (Scalar v))) -> Envelope 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), the trace computes the distance from
--   the base point along the line to the first intersection with the
--   diagram. The distance can be negative if the intersection is in the
--   opposite direction from the base point, or infinite if the ray never
--   intersects the diagram. Note: to obtain the distance to the
--   <i>furthest</i> intersection instead of the <i>closest</i>, just
--   negate the direction vector and then negate the result.
--   
--   Note that the output should actually be interpreted not as an absolute
--   distance, but as a multiplier relative to the input vector. That is,
--   if the input vector is <tt>v</tt> and the returned scalar is
--   <tt>s</tt>, the distance from the base point to the intersection is
--   given by <tt>s * magnitude v</tt>.
newtype Trace v
Trace :: (Point v -> v -> PosInf (Scalar v)) -> Trace v
appTrace :: Trace v -> Point v -> v -> PosInf (Scalar v)
inTrace :: ((Point v -> v -> PosInf (Scalar v)) -> (Point v -> v -> PosInf (Scalar v))) -> Trace v -> Trace v
mkTrace :: (Point v -> v -> PosInf (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 to the boundary of the given
--   object in the given direction, or <tt>Nothing</tt> if there is no
--   intersection.
traceV :: Traced a => Point (V a) -> V a -> a -> Maybe (V a)

-- | Given a base point and direction, compute the closest point on the
--   boundary of the given object, or <tt>Nothing</tt> if there is no
--   intersection in the given direction.
traceP :: Traced a => Point (V a) -> V a -> a -> Maybe (Point (V a))

-- | Like <a>traceV</a>, but computes a vector to the *furthest* point on
--   the boundary instead of the closest.
maxTraceV :: Traced a => Point (V a) -> V a -> a -> Maybe (V a)

-- | Like <a>traceP</a>, but computes the *furthest* point on the boundary
--   instead of the closest.
maxTraceP :: Traced 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)

-- | A type class for primitive things which know how to handle being
--   transformed by both a normal transformation and a "frozen"
--   transformation. The default implementation simply applies both. At the
--   moment, <tt>ScaleInv</tt> is the only type with a non-default instance
--   of <a>IsPrim</a>.
class Transformable p => IsPrim p where transformWithFreeze t1 t2 = transform (t1 <> t2)
transformWithFreeze :: IsPrim p => Transformation (V p) -> Transformation (V p) -> p -> p

-- | The null primitive, which every backend can render by doing nothing.
nullPrim :: (HasLinearMap v, Monoid (Render b v)) => Prim b v

-- | The fundamental diagram type is represented by trees of primitives
--   with various monoidal annotations. The <tt>Q</tt> in <tt>QDiagram</tt>
--   stands for "Queriable", as distinguished from <a>Diagram</a>, a
--   synonym for <tt>QDiagram</tt> with the query type specialized to
--   <a>Any</a>.
data QDiagram b v m

-- | 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

-- | 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

-- | Extract a list of primitives from a diagram, together with their
--   associated transformations and styles.
prims :: HasLinearMap v => QDiagram b v m -> [(Prim b v, (Split (Transformation v), Style v))]

-- | Get the envelope of a diagram.
envelope :: Ord (Scalar v) => QDiagram b v m -> Envelope v

-- | Get the trace of a diagram.
trace :: (Ord (Scalar v), VectorSpace v, HasLinearMap v) => QDiagram b v m -> Trace v

-- | Get the subdiagram map (<i>i.e.</i> an association from names to
--   subdiagrams) of a diagram.
subMap :: QDiagram b v m -> SubMap b v m

-- | Get a list of names of subdiagrams and their locations.
names :: HasLinearMap 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.
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 => 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 => 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 => [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

-- | By default, diagram attributes are not affected by transformations.
--   This means, for example, that <tt>lw 0.01 circle</tt> and <tt>scale 2
--   (lw 0.01 circle)</tt> will be drawn with lines of the <i>same</i>
--   width, and <tt>scaleY 3 circle</tt> will be an ellipse drawn with a
--   uniform line. Once a diagram is frozen, however, transformations do
--   affect attributes, so, for example, <tt>scale 2 (freeze (lw 0.01
--   circle))</tt> will be drawn with a line twice as thick as <tt>lw 0.01
--   circle</tt>, and <tt>scaleY 3 (freeze circle)</tt> will be drawn with
--   a "stretched", variable-width line.
--   
--   Another way of thinking about it is that pre-<tt>freeze</tt>, we are
--   transforming the "abstract idea" of a diagram, and the transformed
--   version is then drawn; when doing a <tt>freeze</tt>, we produce a
--   concrete drawing of the diagram, and it is this visual representation
--   itself which is acted upon by subsequent transformations.
freeze :: (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

-- | 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

-- | 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 the three associated types and implementations for
--   <a>withStyle</a> and <a>doRender</a>.
class (HasLinearMap v, Monoid (Render b v)) => Backend b v where data family Render b v :: * type family Result b v :: * data family Options b v :: * adjustDia _ o d = (o, d) renderDia b opts d = doRender b opts' . mconcat . map renderOne . prims $ d' where (opts', d') = adjustDia b opts d renderOne :: (Prim b v, (Split (Transformation v), Style v)) -> Render b v renderOne (p, (M t, s)) = withStyle b s mempty (render b (transform t p)) renderOne (p, (t1 :| t2, s)) = withStyle b s t1 (render b (transformWithFreeze t1 t2 p))
withStyle :: Backend b v => b -> Style v -> Transformation v -> Render b v -> Render b v
doRender :: Backend b v => b -> Options b v -> Render b v -> Result b v
adjustDia :: (Backend b v, Monoid' m) => b -> Options b v -> QDiagram b v m -> (Options b v, QDiagram b v m)
renderDia :: (Backend b v, InnerSpace v, OrderedField (Scalar v), Monoid' m) => b -> Options b v -> QDiagram b v m -> Result b v

-- | A class for backends which support rendering multiple diagrams, e.g.
--   to a multi-page pdf or something similar.
class Backend b v => MultiBackend b v
renderDias :: (MultiBackend b v, InnerSpace v, OrderedField (Scalar v), Monoid' m) => b -> Options b v -> [QDiagram b v m] -> 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)

-- | 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 `image'
--       Possible fix:
--         add an instance declaration for
--         (Renderable Diagrams.TwoD.Image.Image b0)
--       In the first argument of `width', namely
--         `(image "foo.png" 200 200)'
--       In the expression: width (image "foo.png" 200 200)
--       In an equation for `it': 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 `R2'
--       In the expression: width (circle 1)
--       In an equation for `it': 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
