-- 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.5.1.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. The resulting vector space has kind <tt>*
--   -&gt; *</tt> which means it takes another value (a number) and returns
--   a concrete vector. For example <tt>V2</tt> has kind <tt>* -&gt; *</tt>
--   and <tt>V2 Double</tt> is a vector.
type family V a :: Type -> Type

-- | The numerical field for the object, the number type used for
--   calculations.
type family N a

-- | Convenient type alias to retrieve the vector type associated with an
--   object's vector space. This is usually used as <tt>Vn a ~ v n</tt>
--   where <tt>v</tt> is the vector space and <tt>n</tt> is the numerical
--   field.
type Vn a = V a N a

-- | <tt>InSpace v n a</tt> means the type <tt>a</tt> belongs to the vector
--   space <tt>v n</tt>, where <tt>v</tt> is <a>Additive</a> and <tt>n</tt>
--   is a <a>Num</a>.
type InSpace (v :: Type -> Type) n a = (V a ~ v, N a ~ n, Additive v, Num n)

-- | <tt>SameSpace a b</tt> means the types <tt>a</tt> and <tt>b</tt>
--   belong to the same vector space <tt>v n</tt>.
type SameSpace a b = (V a ~ V b, N a ~ N b)


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

-- | A handy wrapper to help distinguish points from vectors at the type
--   level
newtype Point (f :: Type -> Type) a
P :: f a -> Point (f :: Type -> Type) a

-- | Vector spaces have origins.
origin :: forall (f :: Type -> Type) a. (Additive f, Num a) => Point f a

-- | Scale a point by a scalar. Specialized version of <a>(*^)</a>.
(*.) :: forall (v :: Type -> Type) n. (Functor v, Num n) => n -> Point v n -> Point v n

-- | An isomorphism between points and vectors, given a reference point.
relative :: forall (f :: Type -> Type) a. (Additive f, Num a) => Point f a -> Iso' (Point f a) (f a)
_Point :: forall f1 a g b p f2. (Profunctor p, Functor f2) => p (f1 a) (f2 (g b)) -> p (Point f1 a) (f2 (Point g b))

-- | Mirror a point through a given point.
reflectThrough :: forall (v :: Type -> Type) n. (Additive v, Num n) => Point v n -> Point v n -> Point v n

-- | Reflect a point across the origin.
mirror :: forall (v :: Type -> Type) n. (Additive v, Num n) => Point v n -> Point v n

-- | Apply a transformation relative to the given point.
relative2 :: (Additive v, Num n) => Point v n -> (v n -> v n -> v n) -> Point v n -> Point v n -> Point v n

-- | Apply a transformation relative to the given point.
relative3 :: (Additive v, Num n) => Point v n -> (v n -> v n -> v n -> v n) -> Point v n -> Point v n -> Point v n -> Point v n

module Diagrams.Core.Measure

-- | 'Measured n a' is an object that depends on <a>local</a>,
--   <a>normalized</a> and <a>global</a> scales. The <a>normalized</a> and
--   <a>global</a> scales are calculated when rendering a diagram.
--   
--   For attributes, the <a>local</a> scale gets multiplied by the average
--   scale of the transform.
newtype Measured n a
Measured :: ((n, n, n) -> a) -> Measured n a
[unmeasure] :: Measured n a -> (n, n, n) -> a

-- | A measure is a <a>Measured</a> number.
type Measure n = Measured n n

-- | <pre>
--   fromMeasured globalScale normalizedScale measure -&gt; a
--   </pre>
fromMeasured :: Num n => n -> n -> Measured n a -> a

-- | Output units don't change.
output :: n -> Measure n

-- | Local units are scaled by the average scale of a transform.
local :: Num n => n -> Measure n

-- | Global units are scaled so that they are interpreted relative to the
--   size of the final rendered diagram.
global :: Num n => n -> Measure n

-- | Normalized units get scaled so that one normalized unit is the size of
--   the final diagram.
normalized :: Num n => n -> Measure n

-- | Just like <a>normalized</a> but spelt properly.
normalised :: Num n => n -> Measure n

-- | Scale the local units of a <a>Measured</a> thing.
scaleLocal :: Num n => n -> Measured n a -> Measured n a

-- | Calculate the larger of two measures.
atLeast :: Ord n => Measure n -> Measure n -> Measure n

-- | Calculate the smaller of two measures.
atMost :: Ord n => Measure n -> Measure n -> Measure n
instance Linear.Vector.Additive (Diagrams.Core.Measure.Measured n)
instance GHC.Internal.Base.Applicative (Diagrams.Core.Measure.Measured n)
instance Data.Distributive.Distributive (Diagrams.Core.Measure.Measured n)
instance GHC.Internal.Float.Floating a => GHC.Internal.Float.Floating (Diagrams.Core.Measure.Measured n a)
instance GHC.Internal.Real.Fractional a => GHC.Internal.Real.Fractional (Diagrams.Core.Measure.Measured n a)
instance GHC.Internal.Base.Functor (Diagrams.Core.Measure.Measured n)
instance GHC.Internal.Base.Monad (Diagrams.Core.Measure.Measured n)
instance Control.Monad.Reader.Class.MonadReader (n, n, n) (Diagrams.Core.Measure.Measured n)
instance GHC.Internal.Base.Monoid a => GHC.Internal.Base.Monoid (Diagrams.Core.Measure.Measured n a)
instance GHC.Internal.Num.Num a => GHC.Internal.Num.Num (Diagrams.Core.Measure.Measured n a)
instance Data.Profunctor.Unsafe.Profunctor Diagrams.Core.Measure.Measured
instance Data.Functor.Rep.Representable (Diagrams.Core.Measure.Measured n)
instance GHC.Internal.Base.Semigroup a => GHC.Internal.Base.Semigroup (Diagrams.Core.Measure.Measured n a)


-- | 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 (negated 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 HasOrigin t

-- | Move the local origin to another point.
--   
--   Note that this function is in some sense dual to <tt>translate</tt>
--   (for types which are also <tt>Transformable</tt>); moving the origin
--   itself while leaving the object "fixed" is dual to fixing the origin
--   and translating the diagram.
moveOriginTo :: HasOrigin t => Point (V t) (N t) -> t -> t

-- | Move the local origin by a relative vector.
moveOriginBy :: (V t ~ v, N t ~ n, HasOrigin t) => v n -> 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 :: forall (v :: Type -> Type) n t. (InSpace v n t, HasOrigin t) => Point v n -> 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 :: forall (v :: Type -> Type) n t. (InSpace v n t, HasOrigin t) => t -> Point v n -> t
instance Diagrams.Core.HasOrigin.HasOrigin t => Diagrams.Core.HasOrigin.HasOrigin [t]
instance Diagrams.Core.HasOrigin.HasOrigin t => Diagrams.Core.HasOrigin.HasOrigin (Data.Map.Internal.Map k t)
instance Diagrams.Core.HasOrigin.HasOrigin t => Diagrams.Core.HasOrigin.HasOrigin (Diagrams.Core.Measure.Measured n t)
instance (Linear.Vector.Additive v, GHC.Internal.Num.Num n) => Diagrams.Core.HasOrigin.HasOrigin (Linear.Affine.Point v n)
instance (Diagrams.Core.HasOrigin.HasOrigin t, GHC.Classes.Ord t) => Diagrams.Core.HasOrigin.HasOrigin (Data.Set.Internal.Set t)
instance (Diagrams.Core.HasOrigin.HasOrigin t, Diagrams.Core.HasOrigin.HasOrigin s, Diagrams.Core.V.SameSpace s t) => Diagrams.Core.HasOrigin.HasOrigin (s, t)


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

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

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

-- | Apply a linear map to a vector.
lapp :: (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. (For a more detailed explanation and proof, see
--   <a>https://wiki.haskell.org/Diagrams/Dev/Transformations</a>.) 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-invertible transformations, see
--   <tt>Diagrams.Deform</tt> (in <tt>diagrams-lib</tt>).
data Transformation (v :: Type -> Type) n
Transformation :: (v n :-: v n) -> (v n :-: v n) -> v n -> Transformation (v :: Type -> Type) n

-- | Invert a transformation.
inv :: forall (v :: Type -> Type) n. (Functor v, Num n) => Transformation v n -> Transformation v n

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

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

-- | Drop the translational component of a transformation, leaving only the
--   linear part.
dropTransl :: forall (v :: Type -> Type) n. (Additive v, Num n) => Transformation v n -> Transformation v n

-- | 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 :: Transformation v n -> v n -> v n

-- | Apply a transformation to a point.
papply :: forall (v :: Type -> Type) n. (Additive v, Num n) => Transformation v n -> Point v n -> Point v n

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

-- | An orthogonal linear map is one whose inverse is also its transpose.
fromOrthogonal :: (Additive v, Num n) => (v n :-: v n) -> Transformation v n

-- | A symmetric linear map is one whose transpose is equal to its self.
fromSymmetric :: (Additive v, Num n) => (v n :-: v n) -> Transformation v n

-- | Produce a default basis for a vector space. If the dimensionality of
--   the vector space is not statically known, see <a>basisFor</a>.
basis :: (Additive t, Traversable t, Num a) => [t a]

-- | Get the dimension of an object whose vector space is an instance of
--   <tt>HasLinearMap</tt>, e.g. transformations, paths, diagrams, etc.
dimension :: (Additive (V a), Traversable (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 :: (Additive v, Traversable v, Num n) => Transformation v n -> ([v n], v n)

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

-- | Convert the linear part of a <a>Transformation</a> to a matrix
--   representation as a list of column vectors which are also lists.
matrixRep :: forall (v :: Type -> Type) n. (Additive v, Traversable v, Num n) => Transformation v n -> [[n]]

-- | 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 :: forall (v :: Type -> Type) n. (Additive v, Traversable v, Num n) => Transformation v n -> [[n]]

-- | The determinant of (the linear part of) a <a>Transformation</a>.
determinant :: forall (v :: Type -> Type) n. (Additive v, Traversable v, Num n) => Transformation v n -> n

-- | Determine whether a <a>Transformation</a> includes a reflection
--   component, that is, whether it reverses orientation.
isReflection :: forall (v :: Type -> Type) n. (Additive v, Traversable v, Num n, Ord n) => Transformation v n -> Bool

-- | Compute the "average" amount of scaling performed by a transformation.
--   Satisfies the properties
--   
--   <pre>
--   avgScale (scaling k) == k
--   avgScale (t1 &lt;&gt; t2)  == avgScale t1 * avgScale t2
--   
--   </pre>
avgScale :: forall (v :: Type -> Type) n. (Additive v, Traversable v, Floating n) => Transformation v n -> n

-- | Identity matrix.
eye :: (HasBasis v, Num n) => v (v n)

-- | <a>HasLinearMap</a> is a constraint synonym, just to help shorten some
--   of the ridiculously long constraint sets.
type HasLinearMap (v :: Type -> Type) = (HasBasis v, Traversable v)

-- | An <a>Additive</a> vector space whose representation is made up of
--   basis elements.
type HasBasis (v :: Type -> Type) = (Additive v, Representable v, Rep v ~ E v)

-- | Type class for things <tt>t</tt> which can be transformed.
class Transformable t

-- | Apply a transformation to an object.
transform :: Transformable t => Transformation (V t) (N 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 :: v n -> Transformation v n

-- | Translate by a vector.
translate :: Transformable t => Vn t -> t -> t

-- | Create a uniform scaling transformation.
scaling :: forall (v :: Type -> Type) n. (Additive v, Fractional n) => n -> Transformation v n

-- | Scale uniformly in every dimension by the given scalar.
scale :: forall (v :: Type -> Type) n a. (InSpace v n a, Eq n, Fractional n, Transformable a) => n -> a -> a
instance (Diagrams.Core.Transform.Transformable a, Diagrams.Core.V.V a GHC.Types.~ v, Diagrams.Core.V.N a GHC.Types.~ n) => Data.Monoid.Action.Action (Diagrams.Core.Transform.Transformation v n) a
instance GHC.Classes.Eq t => GHC.Classes.Eq (Diagrams.Core.Transform.TransInv t)
instance Diagrams.Core.HasOrigin.HasOrigin (Diagrams.Core.Transform.TransInv t)
instance (Linear.Vector.Additive v, GHC.Internal.Num.Num n) => Diagrams.Core.HasOrigin.HasOrigin (Diagrams.Core.Transform.Transformation v n)
instance GHC.Internal.Base.Monoid (v Diagrams.Core.Transform.:-: v)
instance GHC.Internal.Base.Monoid t => GHC.Internal.Base.Monoid (Diagrams.Core.Transform.TransInv t)
instance (Linear.Vector.Additive v, GHC.Internal.Num.Num n) => GHC.Internal.Base.Monoid (Diagrams.Core.Transform.Transformation v n)
instance GHC.Classes.Ord t => GHC.Classes.Ord (Diagrams.Core.Transform.TransInv t)
instance Control.Lens.Wrapped.Rewrapped (Diagrams.Core.Transform.TransInv t) (Diagrams.Core.Transform.TransInv t')
instance GHC.Internal.Base.Semigroup (a Diagrams.Core.Transform.:-: a)
instance GHC.Internal.Base.Semigroup t => GHC.Internal.Base.Semigroup (Diagrams.Core.Transform.TransInv t)
instance (Linear.Vector.Additive v, GHC.Internal.Num.Num n) => GHC.Internal.Base.Semigroup (Diagrams.Core.Transform.Transformation v n)
instance GHC.Internal.Show.Show t => GHC.Internal.Show.Show (Diagrams.Core.Transform.TransInv t)
instance Diagrams.Core.Transform.Transformable m => Diagrams.Core.Transform.Transformable (Data.Monoid.Deletable.Deletable m)
instance (Diagrams.Core.V.V t GHC.Types.~ v, Diagrams.Core.V.N t GHC.Types.~ n, Diagrams.Core.V.V t GHC.Types.~ Diagrams.Core.V.V s, Diagrams.Core.V.N t GHC.Types.~ Diagrams.Core.V.N s, GHC.Internal.Base.Functor v, GHC.Internal.Num.Num n, Diagrams.Core.Transform.Transformable t, Diagrams.Core.Transform.Transformable s) => Diagrams.Core.Transform.Transformable (s -> t)
instance Diagrams.Core.Transform.Transformable t => Diagrams.Core.Transform.Transformable [t]
instance Diagrams.Core.Transform.Transformable t => Diagrams.Core.Transform.Transformable (Data.Map.Internal.Map k t)
instance (Diagrams.Core.V.InSpace v n t, Diagrams.Core.Transform.Transformable t, Diagrams.Core.Transform.HasLinearMap v, GHC.Internal.Float.Floating n) => Diagrams.Core.Transform.Transformable (Diagrams.Core.Measure.Measured n t)
instance (Linear.Vector.Additive v, GHC.Internal.Num.Num n) => Diagrams.Core.Transform.Transformable (Linear.Affine.Point v n)
instance (Diagrams.Core.Transform.Transformable t, GHC.Classes.Ord t) => Diagrams.Core.Transform.Transformable (Data.Set.Internal.Set t)
instance (GHC.Internal.Num.Num (Diagrams.Core.V.N t), Linear.Vector.Additive (Diagrams.Core.V.V t), Diagrams.Core.Transform.Transformable t) => Diagrams.Core.Transform.Transformable (Diagrams.Core.Transform.TransInv t)
instance (Linear.Vector.Additive v, GHC.Internal.Num.Num n) => Diagrams.Core.Transform.Transformable (Diagrams.Core.Transform.Transformation v n)
instance (Diagrams.Core.Transform.Transformable t, Diagrams.Core.Transform.Transformable s, Diagrams.Core.V.V t GHC.Types.~ Diagrams.Core.V.V s, Diagrams.Core.V.N t GHC.Types.~ Diagrams.Core.V.N s) => Diagrams.Core.Transform.Transformable (t, s)
instance (Diagrams.Core.Transform.Transformable t, Diagrams.Core.Transform.Transformable s, Diagrams.Core.Transform.Transformable u, Diagrams.Core.V.V s GHC.Types.~ Diagrams.Core.V.V t, Diagrams.Core.V.N s GHC.Types.~ Diagrams.Core.V.N t, Diagrams.Core.V.V s GHC.Types.~ Diagrams.Core.V.V u, Diagrams.Core.V.N s GHC.Types.~ Diagrams.Core.V.N u) => Diagrams.Core.Transform.Transformable (t, s, u)
instance Control.Lens.Wrapped.Wrapped (Diagrams.Core.Transform.TransInv t)


-- | 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 :: Type -> Type) n
[Attribute] :: forall a (v :: Type -> Type) n. AttributeClass a => a -> Attribute v n
[MAttribute] :: forall a n (v :: Type -> Type). AttributeClass a => Measured n a -> Attribute v n
[TAttribute] :: forall a (v :: Type -> Type) n. (AttributeClass a, Transformable a, V a ~ v, N a ~ n) => a -> Attribute v n

-- | Prism onto an <a>Attribute</a>.
_Attribute :: forall a (v :: Type -> Type) n. AttributeClass a => Prism' (Attribute v n) a

-- | Prism onto an <a>MAttribute</a>.
_MAttribute :: forall a n (v :: Type -> Type). (AttributeClass a, Typeable n) => Prism' (Attribute v n) (Measured n a)

-- | Prism onto a <a>TAttribute</a>.
_TAttribute :: forall a (v :: Type -> Type) n. (V a ~ v, N a ~ n, AttributeClass a, Transformable a) => Prism' (Attribute v n) a

-- | 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.
--   
--   Measured attributes cannot be extrated from this function until they
--   have been unmeasured with <a>unmeasureAttribute</a>. If you want a
--   measured attibute use the <a>_MAttribute</a> prism.
unwrapAttribute :: forall a (v :: Type -> Type) n. AttributeClass a => Attribute v n -> Maybe a

-- | Turn an <a>MAttribute</a> into an <a>Attribute</a> using the given
--   <a>global</a> and <a>normalized</a> scale.
unmeasureAttribute :: forall n (v :: Type -> Type). Num n => n -> n -> Attribute v n -> Attribute v n

-- | Type of an attribute that is stored with a style. Measured attributes
--   return the type as if it where unmeasured.
attributeType :: forall (v :: Type -> Type) n. Attribute v n -> TypeRep

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

-- | Turn an attribute into a style. An easier way to make a style is to
--   use the monoid instance and apply library functions for applying that
--   attribute:
--   
--   <pre>
--   myStyle = mempty # fc blue :: Style V2 Double
--   </pre>
attributeToStyle :: forall (v :: Type -> Type) n. Attribute v n -> Style v n

-- | 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.
--   
--   Trying to extract a measured attibute will fail. It either has to be
--   unmeasured with <a>unmeasureAttrs</a> or use the <a>atMAttr</a> lens.
getAttr :: forall a (v :: Type -> Type) n. AttributeClass a => Style v n -> Maybe a

-- | Replace all <a>MAttribute</a>s with <a>Attribute</a>s using the
--   <a>global</a> and <a>normalized</a> scales.
unmeasureAttrs :: forall n (v :: Type -> Type). Num n => n -> n -> Style v n -> Style v n

-- | Lens onto a plain attribute of a style.
atAttr :: forall a (v :: Type -> Type) n. AttributeClass a => Lens' (Style v n) (Maybe a)

-- | Lens onto a measured attribute of a style.
atMAttr :: forall a n (v :: Type -> Type). (AttributeClass a, Typeable n) => Lens' (Style v n) (Maybe (Measured n a))

-- | Lens onto a transformable attribute of a style.
atTAttr :: forall a (v :: Type -> Type) n. (V a ~ v, N a ~ n, AttributeClass a, Transformable a) => Lens' (Style v n) (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 measured 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.
applyMAttr :: (AttributeClass a, N d ~ n, HasStyle d) => Measured n 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, N a ~ N d, HasStyle d) => a -> d -> d

-- | Type class for things which have a style.
class HasStyle a

-- | <i>Apply</i> a style by combining it (on the left) with the existing
--   style.
applyStyle :: HasStyle a => Style (V a) (N a) -> a -> a
instance Data.Monoid.Action.Action (Diagrams.Core.Style.Style v n) m
instance Control.Lens.At.At (Diagrams.Core.Style.Style v n)
instance Control.Lens.Each.Each (Diagrams.Core.Style.Style v n) (Diagrams.Core.Style.Style v' n') (Diagrams.Core.Style.Attribute v n) (Diagrams.Core.Style.Attribute v' n')
instance Diagrams.Core.Style.HasStyle b => Diagrams.Core.Style.HasStyle (a -> b)
instance Diagrams.Core.Style.HasStyle a => Diagrams.Core.Style.HasStyle [a]
instance Diagrams.Core.Style.HasStyle a => Diagrams.Core.Style.HasStyle (Data.Map.Internal.Map k a)
instance Diagrams.Core.Style.HasStyle b => Diagrams.Core.Style.HasStyle (Diagrams.Core.Measure.Measured n b)
instance (Diagrams.Core.Style.HasStyle a, GHC.Classes.Ord a) => Diagrams.Core.Style.HasStyle (Data.Set.Internal.Set a)
instance GHC.Internal.Data.Typeable.Internal.Typeable n => Diagrams.Core.Style.HasStyle (Diagrams.Core.Style.Style v n)
instance (Diagrams.Core.Style.HasStyle a, Diagrams.Core.Style.HasStyle b, Diagrams.Core.V.V a GHC.Types.~ Diagrams.Core.V.V b, Diagrams.Core.V.N a GHC.Types.~ Diagrams.Core.V.N b) => Diagrams.Core.Style.HasStyle (a, b)
instance Control.Lens.At.Ixed (Diagrams.Core.Style.Style v n)
instance GHC.Internal.Data.Typeable.Internal.Typeable n => GHC.Internal.Base.Monoid (Diagrams.Core.Style.Style v n)
instance Control.Lens.Wrapped.Rewrapped (Diagrams.Core.Style.Style v n) (Diagrams.Core.Style.Style v' n')
instance GHC.Internal.Data.Typeable.Internal.Typeable n => GHC.Internal.Base.Semigroup (Diagrams.Core.Style.Attribute v n)
instance GHC.Internal.Data.Typeable.Internal.Typeable n => GHC.Internal.Base.Semigroup (Diagrams.Core.Style.Style v n)
instance GHC.Internal.Show.Show (Diagrams.Core.Style.Attribute v n)
instance GHC.Internal.Show.Show (Diagrams.Core.Style.Style v n)
instance (Linear.Vector.Additive v, GHC.Internal.Data.Traversable.Traversable v, GHC.Internal.Float.Floating n) => Diagrams.Core.Transform.Transformable (Diagrams.Core.Style.Attribute v n)
instance (Linear.Vector.Additive v, GHC.Internal.Data.Traversable.Traversable v, GHC.Internal.Float.Floating n) => Diagrams.Core.Transform.Transformable (Diagrams.Core.Style.Style v n)
instance Control.Lens.Wrapped.Wrapped (Diagrams.Core.Style.Style v n)


-- | 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] :: forall a. (Typeable a, Ord a, Show a) => a -> AName

-- | Prism onto <a>AName</a>.
_AName :: (Typeable a, Ord a, Show a) => Prism' AName a

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

-- | Traversal over each name in a <a>Name</a> that matches the target
--   type.
--   
--   <pre>
--   &gt;&gt;&gt; toListOf eachName (<tt>a</tt> .&gt; False .&gt; <tt>b</tt>) :: String
--   "ab"
--   &gt;&gt;&gt; <tt>a</tt> .&gt; True .&gt; <tt>b</tt> &amp; eachName %~ not
--   <tt>a</tt> .&gt; False .&gt; <tt>b</tt>
--   </pre>
--   
--   Note that the type of the name is very important.
--   
--   <pre>
--   &gt;&gt;&gt; sumOf eachName ((1::Int) .&gt; (2 :: Integer) .&gt; (3 :: Int)) :: Int
--   4
--   &gt;&gt;&gt; sumOf eachName ((1::Int) .&gt; (2 :: Integer) .&gt; (3 :: Int)) :: Integer
--   2
--   </pre>
eachName :: (Typeable a, Ord a, Show a) => Traversal' Name a

-- | Instances of <a>Qualifiable</a> are things which can be qualified by
--   prefixing them with a name.
class Qualifiable q

-- | Qualify with the given name.
(.>>) :: (Qualifiable q, IsName a) => a -> q -> q
infixr 5 .>>
instance Control.Lens.Each.Each Diagrams.Core.Names.Name Diagrams.Core.Names.Name Diagrams.Core.Names.AName Diagrams.Core.Names.AName
instance GHC.Classes.Eq Diagrams.Core.Names.AName
instance GHC.Classes.Eq Diagrams.Core.Names.Name
instance Diagrams.Core.Names.IsName Diagrams.Core.Names.AName
instance Diagrams.Core.Names.IsName GHC.Types.Bool
instance Diagrams.Core.Names.IsName GHC.Types.Char
instance Diagrams.Core.Names.IsName GHC.Types.Double
instance Diagrams.Core.Names.IsName GHC.Types.Float
instance Diagrams.Core.Names.IsName GHC.Types.Int
instance Diagrams.Core.Names.IsName GHC.Num.Integer.Integer
instance Diagrams.Core.Names.IsName a => Diagrams.Core.Names.IsName [a]
instance Diagrams.Core.Names.IsName a => Diagrams.Core.Names.IsName (GHC.Internal.Maybe.Maybe a)
instance Diagrams.Core.Names.IsName Diagrams.Core.Names.Name
instance (Diagrams.Core.Names.IsName a, Diagrams.Core.Names.IsName b) => Diagrams.Core.Names.IsName (a, b)
instance (Diagrams.Core.Names.IsName a, Diagrams.Core.Names.IsName b, Diagrams.Core.Names.IsName c) => Diagrams.Core.Names.IsName (a, b, c)
instance Diagrams.Core.Names.IsName ()
instance GHC.Internal.Base.Monoid Diagrams.Core.Names.Name
instance GHC.Classes.Ord Diagrams.Core.Names.AName
instance GHC.Classes.Ord Diagrams.Core.Names.Name
instance Diagrams.Core.Names.Qualifiable a => Diagrams.Core.Names.Qualifiable (b -> a)
instance Diagrams.Core.Names.Qualifiable a => Diagrams.Core.Names.Qualifiable [a]
instance Diagrams.Core.Names.Qualifiable a => Diagrams.Core.Names.Qualifiable (Data.Map.Internal.Map k a)
instance Diagrams.Core.Names.Qualifiable a => Diagrams.Core.Names.Qualifiable (Diagrams.Core.Measure.Measured n a)
instance Diagrams.Core.Names.Qualifiable Diagrams.Core.Names.Name
instance (GHC.Classes.Ord a, Diagrams.Core.Names.Qualifiable a) => Diagrams.Core.Names.Qualifiable (Data.Set.Internal.Set a)
instance Diagrams.Core.Names.Qualifiable a => Diagrams.Core.Names.Qualifiable (Diagrams.Core.Transform.TransInv a)
instance (Diagrams.Core.Names.Qualifiable a, Diagrams.Core.Names.Qualifiable b) => Diagrams.Core.Names.Qualifiable (a, b)
instance (Diagrams.Core.Names.Qualifiable a, Diagrams.Core.Names.Qualifiable b, Diagrams.Core.Names.Qualifiable c) => Diagrams.Core.Names.Qualifiable (a, b, c)
instance Control.Lens.Wrapped.Rewrapped Diagrams.Core.Names.Name Diagrams.Core.Names.Name
instance GHC.Internal.Base.Semigroup Diagrams.Core.Names.Name
instance GHC.Internal.Show.Show Diagrams.Core.Names.AName
instance GHC.Internal.Show.Show Diagrams.Core.Names.Name
instance Control.Lens.Wrapped.Wrapped Diagrams.Core.Names.Name


-- | <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 :: Type -> Type) n
Trace :: (Point v n -> v n -> SortedList n) -> Trace (v :: Type -> Type) n
appTrace :: Trace v n -> Point v n -> v n -> SortedList n
mkTrace :: (Point v n -> v n -> SortedList n) -> Trace v n

-- | <tt>Traced</tt> abstracts over things which have a trace.
class (Additive V a, Ord N a) => Traced a

-- | Compute the trace of an object.
getTrace :: Traced a => a -> Trace (V a) (N 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 :: (n ~ N a, Num n, Traced a) => Point (V a) n -> V a n -> a -> Maybe (V a n)

-- | 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 :: (n ~ N a, Traced a, Num n) => Point (V a) n -> V a n -> a -> Maybe (Point (V a) n)

-- | 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 :: (n ~ N a, Num n, Traced a) => Point (V a) n -> V a n -> a -> Maybe (V a n)

-- | 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 :: (n ~ N a, Num n, Traced a) => Point (V a) n -> V a n -> a -> Maybe (Point (V a) n)

-- | 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 :: (n ~ N a, Traced a, Num n) => a -> Trace (V a) n

-- | 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 :: (n ~ N a, Traced a, Num n) => Point (V a) n -> V a n -> a -> Maybe (V a n)

-- | 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 :: (n ~ N a, Traced a, Num n) => Point (V a) n -> V a n -> a -> Maybe (Point (V a) n)

-- | 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 :: (n ~ N a, Traced a, Num n) => Point (V a) n -> V a n -> a -> Maybe (V a n)

-- | Like <a>rayTraceP</a>, but computes the "largest" boundary point
--   instead of the smallest. Considers only <i>positive</i> boundary
--   points.
--   
maxRayTraceP :: (n ~ N a, Traced a, Num n) => Point (V a) n -> V a n -> a -> Maybe (Point (V a) n)
instance (Linear.Vector.Additive v, GHC.Internal.Num.Num n) => Diagrams.Core.HasOrigin.HasOrigin (Diagrams.Core.Trace.Trace v n)
instance GHC.Classes.Ord a => GHC.Internal.Base.Monoid (Diagrams.Core.Trace.SortedList a)
instance GHC.Classes.Ord n => GHC.Internal.Base.Monoid (Diagrams.Core.Trace.Trace v n)
instance Control.Lens.Wrapped.Rewrapped (Diagrams.Core.Trace.Trace v n) (Diagrams.Core.Trace.Trace v' n')
instance GHC.Classes.Ord a => GHC.Internal.Base.Semigroup (Diagrams.Core.Trace.SortedList a)
instance GHC.Classes.Ord n => GHC.Internal.Base.Semigroup (Diagrams.Core.Trace.Trace v n)
instance GHC.Internal.Show.Show (Diagrams.Core.Trace.Trace v n)
instance Diagrams.Core.Trace.Traced b => Diagrams.Core.Trace.Traced [b]
instance Diagrams.Core.Trace.Traced b => Diagrams.Core.Trace.Traced (Data.Map.Internal.Map k b)
instance (Linear.Vector.Additive v, GHC.Classes.Ord n) => Diagrams.Core.Trace.Traced (Linear.Affine.Point v n)
instance Diagrams.Core.Trace.Traced b => Diagrams.Core.Trace.Traced (Data.Set.Internal.Set b)
instance (Linear.Vector.Additive v, GHC.Classes.Ord n) => Diagrams.Core.Trace.Traced (Diagrams.Core.Trace.Trace v n)
instance Diagrams.Core.Trace.Traced t => Diagrams.Core.Trace.Traced (Diagrams.Core.Transform.TransInv t)
instance (Diagrams.Core.Trace.Traced a, Diagrams.Core.Trace.Traced b, Diagrams.Core.V.SameSpace a b) => Diagrams.Core.Trace.Traced (a, b)
instance (Linear.Vector.Additive v, GHC.Internal.Num.Num n) => Diagrams.Core.Transform.Transformable (Diagrams.Core.Trace.Trace v n)
instance Control.Lens.Wrapped.Wrapped (Diagrams.Core.Trace.Trace v n)


-- | 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 :: Type -> Type) n m
Query :: (Point v n -> m) -> Query (v :: Type -> Type) n m
[runQuery] :: Query (v :: Type -> Type) n m -> Point v n -> m
instance GHC.Internal.Base.Applicative (Diagrams.Core.Query.Query v n)
instance GHC.Internal.Base.Functor v => Data.Profunctor.Closed.Closed (Diagrams.Core.Query.Query v)
instance GHC.Internal.Base.Functor v => Data.Profunctor.Rep.Corepresentable (Diagrams.Core.Query.Query v)
instance GHC.Internal.Base.Functor v => Data.Profunctor.Sieve.Cosieve (Diagrams.Core.Query.Query v) (Linear.Affine.Point v)
instance GHC.Internal.Base.Functor v => Data.Profunctor.Strong.Costrong (Diagrams.Core.Query.Query v)
instance Data.Distributive.Distributive (Diagrams.Core.Query.Query v n)
instance GHC.Internal.Base.Functor (Diagrams.Core.Query.Query v n)
instance (Linear.Vector.Additive v, GHC.Internal.Num.Num n) => Diagrams.Core.HasOrigin.HasOrigin (Diagrams.Core.Query.Query v n m)
instance GHC.Internal.Base.Monad (Diagrams.Core.Query.Query v n)
instance GHC.Internal.Base.Monoid m => GHC.Internal.Base.Monoid (Diagrams.Core.Query.Query v n m)
instance GHC.Internal.Base.Functor v => Data.Profunctor.Unsafe.Profunctor (Diagrams.Core.Query.Query v)
instance Data.Functor.Rep.Representable (Diagrams.Core.Query.Query v n)
instance Control.Lens.Wrapped.Rewrapped (Diagrams.Core.Query.Query v a m) (Diagrams.Core.Query.Query v' a' m')
instance GHC.Internal.Base.Semigroup m => GHC.Internal.Base.Semigroup (Diagrams.Core.Query.Query v n m)
instance (Linear.Vector.Additive v, GHC.Internal.Num.Num n) => Diagrams.Core.Transform.Transformable (Diagrams.Core.Query.Query v n m)
instance Control.Lens.Wrapped.Wrapped (Diagrams.Core.Query.Query v n m)


-- | diagrams-core defines the core library of primitives forming the basis
--   of an embedded domain-specific language for describing and rendering
--   diagrams.
--   
--   The <tt>Diagrams.Core.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://ozark.hendrix.edu/~yorgey/pub/monoid-pearl.pdf</a>; video:
--   <a>http://www.youtube.com/watch?v=X-8NCkD2vOw</a>.
newtype Envelope (v :: Type -> Type) n
Envelope :: Maybe (v n -> Max n) -> Envelope (v :: Type -> Type) n

-- | "Apply" an envelope by turning it into a function. <tt>Nothing</tt> is
--   returned iff the envelope is empty.
appEnvelope :: Envelope v n -> Maybe (v n -> n)

-- | A convenient way to transform an envelope, by specifying a
--   transformation on the underlying <tt>v n -&gt; n</tt> function. The
--   empty envelope is unaffected.
onEnvelope :: ((v n -> n) -> v n -> n) -> Envelope v n -> Envelope v n

-- | Create an envelope from a <tt>v n -&gt; n</tt> function.
mkEnvelope :: (v n -> n) -> Envelope v n

-- | Create a point envelope for the given point. A point envelope has
--   distance zero to a bounding hyperplane in every direction. Note this
--   is <i>not</i> the same as the empty envelope.
pointEnvelope :: forall n (v :: Type -> Type). (Fractional n, Metric v) => Point v n -> Envelope v n

-- | <tt>Enveloped</tt> abstracts over things which have an envelope.
class (Metric V a, OrderedField N a) => Enveloped a

-- | Compute the envelope of an object. For types with an intrinsic notion
--   of "local origin", the envelope will be based there. Other types (e.g.
--   <tt>Trail</tt>) may have some other default reference point at which
--   the envelope will be based; their instances should document what it
--   is.
getEnvelope :: Enveloped a => a -> Envelope (V a) (N a)

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

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

-- | 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 :: (V a ~ v, N a ~ n, Enveloped a) => v n -> a -> Maybe (n, n)

-- | The smallest positive <i>axis-parallel</i> vector that bounds the
--   envelope of an object.
size :: (V a ~ v, N a ~ n, Enveloped a, HasBasis v) => a -> v n

-- | 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 => Vn a -> a -> Maybe (Vn 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 => Vn a -> a -> Vn a

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

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

-- | Equivalent to the norm of <a>envelopeVMay</a>:
--   
--   <pre>
--   envelopeSMay v x == fmap norm (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 norm. However,
--   it is more efficient than calling norm on the results of those
--   functions.
envelopeSMay :: (V a ~ v, N a ~ n, Enveloped a) => v n -> a -> Maybe n

-- | Equivalent to the norm of <a>envelopeV</a>:
--   
--   <pre>
--   envelopeS v x == norm (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 norm. However, it is
--   more efficient than calling norm on the results of those functions.
envelopeS :: (V a ~ v, N a ~ n, Enveloped a) => v n -> a -> n

-- | 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 constraint as a convenient shorthand.
type OrderedField s = (Floating s, Ord s)
instance (Linear.Metric.Metric v, Diagrams.Core.Envelope.OrderedField n) => Diagrams.Core.Envelope.Enveloped (Diagrams.Core.Envelope.Envelope v n)
instance Diagrams.Core.Envelope.Enveloped b => Diagrams.Core.Envelope.Enveloped [b]
instance Diagrams.Core.Envelope.Enveloped b => Diagrams.Core.Envelope.Enveloped (Data.Map.Internal.Map k b)
instance (Diagrams.Core.Envelope.OrderedField n, Linear.Metric.Metric v) => Diagrams.Core.Envelope.Enveloped (Linear.Affine.Point v n)
instance Diagrams.Core.Envelope.Enveloped b => Diagrams.Core.Envelope.Enveloped (Data.Set.Internal.Set b)
instance Diagrams.Core.Envelope.Enveloped t => Diagrams.Core.Envelope.Enveloped (Diagrams.Core.Transform.TransInv t)
instance (Diagrams.Core.Envelope.Enveloped a, Diagrams.Core.Envelope.Enveloped b, Diagrams.Core.V.V a GHC.Types.~ Diagrams.Core.V.V b, Diagrams.Core.V.N a GHC.Types.~ Diagrams.Core.V.N b) => Diagrams.Core.Envelope.Enveloped (a, b)
instance (Linear.Metric.Metric v, GHC.Internal.Real.Fractional n) => Diagrams.Core.HasOrigin.HasOrigin (Diagrams.Core.Envelope.Envelope v n)
instance GHC.Classes.Ord n => GHC.Internal.Base.Monoid (Diagrams.Core.Envelope.Envelope v n)
instance Control.Lens.Wrapped.Rewrapped (Diagrams.Core.Envelope.Envelope v n) (Diagrams.Core.Envelope.Envelope v' n')
instance GHC.Classes.Ord n => GHC.Internal.Base.Semigroup (Diagrams.Core.Envelope.Envelope v n)
instance GHC.Internal.Show.Show (Diagrams.Core.Envelope.Envelope v n)
instance (Linear.Metric.Metric v, GHC.Internal.Float.Floating n) => Diagrams.Core.Transform.Transformable (Diagrams.Core.Envelope.Envelope v n)
instance Control.Lens.Wrapped.Wrapped (Diagrams.Core.Envelope.Envelope v n)


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

-- | <tt>juxtapose v a1 a2</tt> positions <tt>a2</tt> next to <tt>a1</tt>
--   in the direction of <tt>v</tt>. In particular, place <tt>a2</tt> so
--   that <tt>v</tt> points from the local origin of <tt>a1</tt> towards
--   the old local origin of <tt>a2</tt>; <tt>a1</tt>'s local origin
--   becomes <tt>a2</tt>'s new local origin. The result is just a
--   translated version of <tt>a2</tt>. (In particular, this operation does
--   not <i>combine</i> <tt>a1</tt> and <tt>a2</tt> in any way.)
juxtapose :: Juxtaposable a => Vn 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) => Vn a -> a -> a -> a
instance (Linear.Metric.Metric v, Diagrams.Core.Envelope.OrderedField n) => Diagrams.Core.Juxtapose.Juxtaposable (Diagrams.Core.Envelope.Envelope v n)
instance Diagrams.Core.Juxtapose.Juxtaposable a => Diagrams.Core.Juxtapose.Juxtaposable (b -> a)
instance (Diagrams.Core.Envelope.Enveloped b, Diagrams.Core.HasOrigin.HasOrigin b) => Diagrams.Core.Juxtapose.Juxtaposable [b]
instance (Diagrams.Core.Envelope.Enveloped b, Diagrams.Core.HasOrigin.HasOrigin b) => Diagrams.Core.Juxtapose.Juxtaposable (Data.Map.Internal.Map k b)
instance Diagrams.Core.Juxtapose.Juxtaposable a => Diagrams.Core.Juxtapose.Juxtaposable (Diagrams.Core.Measure.Measured n a)
instance (Diagrams.Core.Envelope.Enveloped b, Diagrams.Core.HasOrigin.HasOrigin b, GHC.Classes.Ord b) => Diagrams.Core.Juxtapose.Juxtaposable (Data.Set.Internal.Set b)
instance (Diagrams.Core.Envelope.Enveloped a, Diagrams.Core.HasOrigin.HasOrigin a, Diagrams.Core.Envelope.Enveloped b, Diagrams.Core.HasOrigin.HasOrigin b, Diagrams.Core.V.V a GHC.Types.~ Diagrams.Core.V.V b, Diagrams.Core.V.N a GHC.Types.~ Diagrams.Core.V.N b) => Diagrams.Core.Juxtapose.Juxtaposable (a, b)


-- | 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
OpacityGroup :: Double -> Annotation
KeyVal :: (String, String) -> Annotation

-- | Apply a static annotation at the root of a diagram.
applyAnnotation :: forall (v :: Type -> Type) n m b. (Metric v, OrderedField n, Semigroup m) => Annotation -> QDiagram b v n m -> QDiagram b v n m

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

-- | Change the transparency of a <a>Diagram</a> as a group.
opacityGroup :: forall (v :: Type -> Type) n m b. (Metric v, OrderedField n, Semigroup m) => Double -> QDiagram b v n m -> QDiagram b v n m

-- | Change the transparency of a <a>Diagram</a> as a group.
groupOpacity :: forall (v :: Type -> Type) n m b. (Metric v, OrderedField n, Semigroup m) => Double -> QDiagram b v n m -> QDiagram b v n m

-- | Apply a general Key-Value annotation
keyVal :: forall (v :: Type -> Type) n m b. (Metric v, OrderedField n, Semigroup m) => (String, String) -> QDiagram b v n m -> QDiagram b v n 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 :: Type -> Type) n m = Deletable Envelope v n ::: Deletable Trace v n ::: Deletable SubMap b v n m ::: Query v n 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 :: Type -> Type) n = Transformation v n :+: Style v n ::: Name ::: ()

-- | Inject a transformation into a default downwards annotation value.
transfToAnnot :: forall (v :: Type -> Type) n. Transformation v n -> DownAnnots v n

-- | Extract the (total) transformation from a downwards annotation value.
transfFromAnnot :: forall (v :: Type -> Type) n. (Additive v, Num n) => DownAnnots v n -> Transformation v n

-- | 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 :: Type -> Type) n m
PrimLeaf :: Prim b v n -> QDiaLeaf b (v :: Type -> Type) n 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 n -> n -> n -> QDiagram b v n m) -> QDiaLeaf b (v :: Type -> Type) n m
withQDiaLeaf :: forall b (v :: Type -> Type) n r m. (Prim b v n -> r) -> ((DownAnnots v n -> n -> n -> QDiagram b v n m) -> r) -> QDiaLeaf b v n 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>V2</tt> (for a two-dimensional diagram) or
--   <tt>V3</tt> (for a three-dimensional diagram).</li>
--   <li><tt>n</tt> represents the numerical field the diagram uses.
--   Typically this will be a concrete numeric type like
--   <tt>Double</tt>.</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 :: Type -> Type) n m
QD :: DUALTree (DownAnnots v n) (UpAnnots b v n m) Annotation (QDiaLeaf b v n m) -> QDiagram b (v :: Type -> Type) n m

-- | <tt>Diagram b</tt> is a synonym for <tt><a>QDiagram</a> b (V b) (N b)
--   <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 v n</tt> or the <tt>value</tt> function.
type Diagram b = QDiagram b V b N b Any

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

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

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

-- | Lens onto the <a>Envelope</a> of a <a>QDiagram</a>.
envelope :: forall n (v :: Type -> Type) m b. (OrderedField n, Metric v, Monoid' m) => Lens' (QDiagram b v n m) (Envelope v n)

-- | Lens onto the <a>Trace</a> of a <a>QDiagram</a>.
trace :: forall (v :: Type -> Type) n m b. (Metric v, OrderedField n, Semigroup m) => Lens' (QDiagram b v n m) (Trace v n)

-- | Lens onto the <a>SubMap</a> of a <a>QDiagram</a> (<i>i.e.</i> an
--   association from names to subdiagrams).
subMap :: forall (v :: Type -> Type) m n b. (Metric v, Semigroup m, OrderedField n) => Lens' (QDiagram b v n m) (SubMap b v n m)

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

-- | Get the query function associated with a diagram.
query :: forall m b (v :: Type -> Type) n. Monoid m => QDiagram b v n m -> Query v n 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 :: forall n (v :: Type -> Type) m b. (OrderedField n, Metric v, Semigroup m) => QDiagram b v n m -> QDiagram b v n m -> QDiagram b v n m
infixl 6 `atop`

-- | 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 :: forall nm (v :: Type -> Type) n m b. (IsName nm, Metric v, OrderedField n, Semigroup m) => (QDiagram b v n m -> Subdiagram b v n m) -> nm -> QDiagram b v n m -> QDiagram b v n m

-- | Lookup the most recent diagram associated with (some qualification of)
--   the given name.
lookupName :: forall nm (v :: Type -> Type) m n b. (IsName nm, Metric v, Semigroup m, OrderedField n) => nm -> QDiagram b v n m -> Maybe (Subdiagram b v n 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 :: forall nm (v :: Type -> Type) m n b. (IsName nm, Metric v, Semigroup m, OrderedField n) => nm -> (Subdiagram b v n m -> QDiagram b v n m -> QDiagram b v n m) -> QDiagram b v n m -> QDiagram b v n 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 :: forall nm (v :: Type -> Type) m n b. (IsName nm, Metric v, Semigroup m, OrderedField n) => nm -> ([Subdiagram b v n m] -> QDiagram b v n m -> QDiagram b v n m) -> QDiagram b v n m -> QDiagram b v n 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 :: forall nm (v :: Type -> Type) m n b. (IsName nm, Metric v, Semigroup m, OrderedField n) => [nm] -> ([Subdiagram b v n m] -> QDiagram b v n m -> QDiagram b v n m) -> QDiagram b v n m -> QDiagram b v n m

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

-- | Replace the envelope of a diagram.
setEnvelope :: forall b (v :: Type -> Type) n m. (OrderedField n, Metric v, Monoid' m) => Envelope v n -> QDiagram b v n m -> QDiagram b v n m

-- | Replace the trace of a diagram.
setTrace :: forall b (v :: Type -> Type) n m. (OrderedField n, Metric v, Semigroup m) => Trace v n -> QDiagram b v n m -> QDiagram b v n 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 :: Type -> Type) n m
Subdiagram :: QDiagram b v n m -> DownAnnots v n -> Subdiagram b (v :: Type -> Type) n m

-- | Turn a diagram into a subdiagram with no accumulated context.
mkSubdiagram :: forall b (v :: Type -> Type) n m. QDiagram b v n m -> Subdiagram b v n 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 :: forall (v :: Type -> Type) n m b. (Metric v, OrderedField n, Semigroup m) => Subdiagram b v n m -> QDiagram b v n m

-- | Extract the "raw" content of a subdiagram, by throwing away the
--   context.
rawSub :: forall b (v :: Type -> Type) n m. Subdiagram b v n m -> QDiagram b v n 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 :: forall (v :: Type -> Type) n b m. (Additive v, Num n) => Subdiagram b v n m -> Point v n

-- | 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 :: forall (v :: Type -> Type) n b m. (Metric v, OrderedField n) => Point v n -> Subdiagram b v n 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 :: Type -> Type) n m
SubMap :: Map Name [Subdiagram b v n m] -> SubMap b (v :: Type -> Type) n m

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

-- | Add a name/diagram association to a submap.
rememberAs :: forall a b (v :: Type -> Type) n m. IsName a => a -> QDiagram b v n m -> SubMap b v n m -> SubMap b v n 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 :: forall nm b (v :: Type -> Type) n m. IsName nm => nm -> SubMap b v n m -> Maybe [Subdiagram b v n m]

-- | A value of type <tt>Prim b v n</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 :: Type -> Type) n
[Prim] :: forall p b. (Transformable p, Typeable p, Renderable p b) => p -> Prim b (V p) (N p)
_Prim :: (Typeable p, Renderable p b) => Prism' (Prim b (V p) (N p)) 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 Backend b (v :: Type -> Type) n where {
    
    -- | An intermediate representation used for rendering primitives.
    --   (Typically, this will be some sort of monad, but it need not be.) The
    --   <a>Renderable</a> class guarantees that a backend will be able to
    --   convert primitives into this type; how these rendered primitives are
    --   combined into an ultimate <a>Result</a> is completely up to the
    --   backend.
    data Render b (v :: Type -> Type) n;
    
    -- | The result of running/interpreting a rendering operation.
    type Result b (v :: Type -> Type) n;
    
    -- | Backend-specific rendering options.
    data Options b (v :: Type -> Type) n;
}

-- | <a>adjustDia</a> allows the backend to make adjustments to the final
--   diagram (e.g. to adjust the size based on the options) before
--   rendering it. It returns a modified options record, the transformation
--   applied to the diagram (which can be used to convert attributes whose
--   value is <tt>Measure</tt>, or transform <i>e.g.</i> screen coordinates
--   back into local diagram coordinates), and the adjusted diagram itself.
--   
--   See the diagrams-lib package (particularly the
--   <tt>Diagrams.TwoD.Adjust</tt> module) for some useful implementations.
adjustDia :: (Backend b v n, Additive v, Monoid' m, Num n) => b -> Options b v n -> QDiagram b v n m -> (Options b v n, Transformation v n, QDiagram b v n m)

-- | Given some options, take a representation of a diagram as a tree and
--   render it. The <a>RTree</a> has already been simplified and has all
--   measurements converted to <tt>Output</tt> units.
renderRTree :: Backend b v n => b -> Options b v n -> RTree b v n Annotation -> Result b v n

-- | 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 :: Type -> Type) n a = Tree DNode b v n a
data DNode b (v :: Type -> Type) n a
DStyle :: Style v n -> DNode b (v :: Type -> Type) n a
DTransform :: Transformation v n -> DNode b (v :: Type -> Type) n a
DAnnot :: a -> DNode b (v :: Type -> Type) n 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 :: Type -> Type) n a
DPrim :: Prim b v n -> DNode b (v :: Type -> Type) n a
DEmpty :: DNode b (v :: Type -> Type) n 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 :: Type -> Type) n a = Tree RNode b v n a
data RNode b (v :: Type -> Type) n a

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

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

-- | Prism onto a style of an <a>RNode</a>.
_RStyle :: forall b (v :: Type -> Type) n a p f. (Choice p, Applicative f) => p (Style v n) (f (Style v n)) -> p (RNode b v n a) (f (RNode b v n a))

-- | Prism onto an annotation of an <a>RNode</a>.
_RAnnot :: forall b (v :: Type -> Type) n a p f. (Choice p, Applicative f) => p a (f a) -> p (RNode b v n a) (f (RNode b v n a))

-- | Prism onto a <a>Prim</a> of an <a>RNode</a>.
_RPrim :: forall b (v :: Type -> Type) n a p f. (Choice p, Applicative f) => p (Prim b v n) (f (Prim b v n)) -> p (RNode b v n a) (f (RNode b v n a))

-- | Prism onto an empty <a>RNode</a>.
_REmpty :: forall b (v :: Type -> Type) n a p f. (Choice p, Applicative f) => p () (f ()) -> p (RNode b v n a) (f (RNode b v n 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 (uncheckedImageRef "foo.png" 200 200))
--   &lt;interactive&gt;:11:8:
--       No instance for (Renderable (DImage n0 External) b0)
--         arising from a use of <tt>image</tt>
--       The type variables <tt>n0</tt>, <tt>b0</tt> are ambiguous
--       Possible fix: add a type signature that fixes these type variable(s)
--       Note: there is a potential instance available:
--         instance Fractional n =&gt; Renderable (DImage n a) NullBackend
--           -- Defined in <a>Image</a>
--       Possible fix:
--         add an instance declaration for
--         (Renderable (DImage n0 External) b0)
--       In the first argument of <tt>width</tt>, namely
--         `(image (uncheckedImageRef "foo.png" 200 200))'
--       In the expression:
--         width (image (uncheckedImageRef "foo.png" 200 200))
--       In an equation for <tt>it</tt>:
--           it = width (image (uncheckedImageRef "foo.png" 200 200))
--   
--   </pre>
--   
--   GHC complains that there is no instance for <tt>Renderable (DImage n0
--   External) 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>n0</tt> and <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>V2</tt> <a>Double</a></tt>, like so:
--   
--   <pre>
--   ghci&gt; width (image (uncheckedImageRef "foo.png" 200 200) :: D V2 Double)
--   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;:12:1:
--       Couldn't match expected type <tt>V2</tt> with actual type `V a0'
--       The type variable <tt>a0</tt> is ambiguous
--       Possible fix: add a type signature that fixes these type variable(s)
--       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>TrailLike</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 V2 Double)
--   1.9999999999999998
--   
--   </pre>
type D (v :: Type -> Type) n = QDiagram NullBackend v n Any

-- | Constraint for numeric types that are <a>RealFloat</a> and
--   <a>Typeable</a>, which often occur together. This is used to shorten
--   shorten type constraint contexts.
type TypeableFloat n = (Typeable n, RealFloat n)

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

-- | Given a token representing the backend and a transformable object,
--   render it in the appropriate rendering context.
render :: Renderable t b => b -> t -> Render b (V t) (N t)
instance Data.Monoid.Action.Action Diagrams.Core.Names.Name a => Data.Monoid.Action.Action Diagrams.Core.Names.Name (Data.Monoid.Deletable.Deletable a)
instance Data.Monoid.Action.Action Diagrams.Core.Names.Name (Diagrams.Core.Envelope.Envelope v n)
instance Data.Monoid.Action.Action Diagrams.Core.Names.Name (Diagrams.Core.Query.Query v n m)
instance Data.Monoid.Action.Action Diagrams.Core.Names.Name (Diagrams.Core.Types.SubMap b v n m)
instance Data.Monoid.Action.Action Diagrams.Core.Names.Name (Diagrams.Core.Trace.Trace v n)
instance Diagrams.Core.Types.Backend Diagrams.Core.Types.NullBackend v n
instance (Linear.Metric.Metric v, Diagrams.Core.Envelope.OrderedField n, Data.Monoid.WithSemigroup.Monoid' m) => Diagrams.Core.Envelope.Enveloped (Diagrams.Core.Types.QDiagram b v n m)
instance (Diagrams.Core.Envelope.OrderedField n, Linear.Metric.Metric v, Data.Monoid.WithSemigroup.Monoid' m) => Diagrams.Core.Envelope.Enveloped (Diagrams.Core.Types.Subdiagram b v n m)
instance GHC.Internal.Base.Functor (Diagrams.Core.Types.QDiaLeaf b v n)
instance GHC.Internal.Base.Functor (Diagrams.Core.Types.QDiagram b v n)
instance GHC.Internal.Base.Functor (Diagrams.Core.Types.SubMap b v n)
instance GHC.Internal.Base.Functor (Diagrams.Core.Types.Subdiagram b v n)
instance (Linear.Metric.Metric v, Diagrams.Core.Envelope.OrderedField n, GHC.Internal.Base.Semigroup m) => Diagrams.Core.HasOrigin.HasOrigin (Diagrams.Core.Types.QDiagram b v n m)
instance (Diagrams.Core.Envelope.OrderedField n, Linear.Metric.Metric v) => Diagrams.Core.HasOrigin.HasOrigin (Diagrams.Core.Types.SubMap b v n m)
instance (Linear.Metric.Metric v, Diagrams.Core.Envelope.OrderedField n) => Diagrams.Core.HasOrigin.HasOrigin (Diagrams.Core.Types.Subdiagram b v n m)
instance (Linear.Metric.Metric v, Diagrams.Core.Envelope.OrderedField n, GHC.Internal.Base.Semigroup m) => Diagrams.Core.Style.HasStyle (Diagrams.Core.Types.QDiagram b v n m)
instance (Linear.Metric.Metric v, Diagrams.Core.Envelope.OrderedField n, Data.Monoid.WithSemigroup.Monoid' m) => Diagrams.Core.Juxtapose.Juxtaposable (Diagrams.Core.Types.QDiagram b v n m)
instance (Linear.Metric.Metric v, Diagrams.Core.Envelope.OrderedField n, GHC.Internal.Base.Semigroup m) => GHC.Internal.Base.Monoid (Diagrams.Core.Types.QDiagram b v n m)
instance GHC.Internal.Base.Monoid (Diagrams.Core.Types.Render Diagrams.Core.Types.NullBackend v n)
instance GHC.Internal.Base.Monoid (Diagrams.Core.Types.SubMap b v n m)
instance (Linear.Metric.Metric v, Diagrams.Core.Envelope.OrderedField n, GHC.Internal.Base.Semigroup m) => Diagrams.Core.Names.Qualifiable (Diagrams.Core.Types.QDiagram b v n m)
instance Diagrams.Core.Names.Qualifiable (Diagrams.Core.Types.SubMap b v n m)
instance Diagrams.Core.Types.Renderable (Diagrams.Core.Types.Prim b v n) b
instance Control.Lens.Wrapped.Rewrapped (Diagrams.Core.Types.QDiagram b v n m) (Diagrams.Core.Types.QDiagram b' v' n' m')
instance Control.Lens.Wrapped.Rewrapped (Diagrams.Core.Types.SubMap b v n m) (Diagrams.Core.Types.SubMap b' v' n' m')
instance (Linear.Metric.Metric v, Diagrams.Core.Envelope.OrderedField n, GHC.Internal.Base.Semigroup m) => GHC.Internal.Base.Semigroup (Diagrams.Core.Types.QDiagram b v n m)
instance GHC.Internal.Base.Semigroup (Diagrams.Core.Types.Render Diagrams.Core.Types.NullBackend v n)
instance GHC.Internal.Base.Semigroup (Diagrams.Core.Types.SubMap b v n m)
instance GHC.Internal.Show.Show Diagrams.Core.Types.Annotation
instance (Linear.Metric.Metric v, Diagrams.Core.Envelope.OrderedField n, GHC.Internal.Base.Semigroup m) => Diagrams.Core.Trace.Traced (Diagrams.Core.Types.QDiagram b v n m)
instance (Diagrams.Core.Envelope.OrderedField n, Linear.Metric.Metric v, GHC.Internal.Base.Semigroup m) => Diagrams.Core.Trace.Traced (Diagrams.Core.Types.Subdiagram b v n m)
instance Diagrams.Core.Transform.Transformable (Diagrams.Core.Types.Prim b v n)
instance (Diagrams.Core.Envelope.OrderedField n, Linear.Metric.Metric v, GHC.Internal.Base.Semigroup m) => Diagrams.Core.Transform.Transformable (Diagrams.Core.Types.QDiagram b v n m)
instance Diagrams.Core.Transform.Transformable (Diagrams.Core.Types.SubMap b v n m)
instance Diagrams.Core.Transform.Transformable (Diagrams.Core.Types.Subdiagram b v n m)
instance Control.Lens.Wrapped.Wrapped (Diagrams.Core.Types.QDiagram b v n m)
instance Control.Lens.Wrapped.Wrapped (Diagrams.Core.Types.SubMap b v n m)


-- | 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 :: Type -> Type) n a

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

-- | A primitive.
RPrim :: Prim b v n -> RNode b (v :: Type -> Type) n a
REmpty :: RNode b (v :: Type -> Type) n 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 :: Type -> Type) n a = Tree RNode b v n 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 :: forall (v :: Type -> Type) n m b. (HasLinearMap v, Metric v, Typeable n, OrderedField n, Monoid m, Semigroup m) => Transformation v n -> QDiagram b v n m -> RTree b v n Annotation

-- | Render a diagram.
renderDia :: forall b (v :: Type -> Type) n m. (Backend b v n, HasLinearMap v, Metric v, Typeable n, OrderedField n, Monoid' m) => b -> Options b v n -> QDiagram b v n m -> Result b v n

-- | 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 :: forall b (v :: Type -> Type) n m. (Backend b v n, HasLinearMap v, Metric v, Typeable n, OrderedField n, Monoid' m) => b -> Options b v n -> QDiagram b v n m -> (Transformation v n, Result b v n)

-- | Convert a <tt>QDiagram</tt> into a raw tree.
toDTree :: forall (v :: Type -> Type) n b m. (HasLinearMap v, Floating n, Typeable n) => n -> n -> QDiagram b v n m -> Maybe (DTree b v n Annotation)

-- | Convert a <tt>DTree</tt> to an <tt>RTree</tt> which can be used
--   directly 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 :: forall b (v :: Type -> Type) n. (Floating n, HasLinearMap v) => DTree b v n Annotation -> RTree b v n Annotation


-- | 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>https://diagrams.github.io/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><ul><li><tt><a>Annotation</a></tt>,</li><li><tt><a>UpAnnots</a>
--   b v n m</tt>, <tt><a>DownAnnots</a> v
--   n</tt>,</li><li><tt><a>QDiaLeaf</a> b v n m</tt>, <tt><a>Measure</a>
--   n</tt>,</li><li><tt><a>Subdiagram</a> b v n m</tt>, <tt><a>SubMap</a>
--   b v n m</tt>,</li><li><tt><a>Prim</a> b v n</tt>, <tt><a>Backend</a> b
--   v n</tt>,</li><li><tt><a>DNode</a> b v n a</tt>, <tt><a>DTree</a> b v
--   n a</tt>,</li><li><tt><a>RNode</a> b v n a</tt>, <tt><a>RTree</a> b v
--   n a</tt>,</li><li><tt><a>NullBackend</a></tt>, <tt><a>Renderable</a> t
--   b</tt>,</li><li><tt><a>D</a> v n</tt>.</li></ul></li>
--   <li><a>Diagrams.Core.Envelope</a><ul><li><tt><a>Envelope</a> v n</tt>,
--   <tt><a>Enveloped</a> a</tt>,</li><li><tt><a>OrderedField</a>
--   s</tt>.</li></ul></li>
--   <li><a>Diagrams.Core.Juxtapose</a><ul><li><tt><a>Juxtaposable</a>
--   a</tt>.</li></ul></li>
--   <li><a>Diagrams.Core.Names</a><ul><li><tt><a>AName</a></tt>,
--   <tt><a>Name</a></tt>, <tt><a>IsName</a>
--   a</tt>,</li><li><tt><a>Qualifiable</a> q</tt>.</li></ul></li>
--   <li><a>Diagrams.Core.HasOrigin</a><ul><li><tt><a>HasOrigin</a>
--   t</tt>.</li></ul></li>
--   <li><a>Diagrams.Core.Query</a><ul><li><tt><a>Query</a> v n
--   m</tt>.</li></ul></li>
--   <li><a>Diagrams.Core.Style</a><ul><li><tt><a>AttributeClass</a>
--   a</tt>, <tt><a>Attribute</a> v n</tt>,</li><li><tt><a>Style</a> v
--   n</tt>, <tt><a>HasStyle</a></tt>.</li></ul></li>
--   <li><a>Diagrams.Core.Trace</a><ul><li><tt><a>SortedList</a>
--   a</tt>,</li><li><tt><a>Trace</a> v n</tt>, <tt><a>Traced</a>
--   a</tt>.</li></ul></li>
--   <li><a>Diagrams.Core.Transform</a><ul><li><tt>u <a>:-:</a> v</tt>,
--   <tt><a>HasLinearMap</a></tt>,
--   <tt><a>HasBasis</a></tt></li><li><tt><a>Transformation</a> v n</tt>,
--   <tt><a>Transformable</a> t</tt>,</li><li><tt><a>TransInv</a>
--   t</tt>.</li></ul></li>
--   <li><a>Diagrams.Core.V</a><ul><li><tt><a>V</a>
--   a</tt>,</li><li><tt><a>N</a> a</tt>,</li><li><tt><a>Vn</a>
--   a</tt>,</li><li><tt><a>InSpace</a> v n
--   a</tt>,</li><li><tt><a>SameSpace</a> a b</tt>.</li></ul></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. The resulting vector space has kind <tt>*
--   -&gt; *</tt> which means it takes another value (a number) and returns
--   a concrete vector. For example <tt>V2</tt> has kind <tt>* -&gt; *</tt>
--   and <tt>V2 Double</tt> is a vector.
type family V a :: Type -> Type

-- | The numerical field for the object, the number type used for
--   calculations.
type family N a

-- | Convenient type alias to retrieve the vector type associated with an
--   object's vector space. This is usually used as <tt>Vn a ~ v n</tt>
--   where <tt>v</tt> is the vector space and <tt>n</tt> is the numerical
--   field.
type Vn a = V a N a

-- | <tt>InSpace v n a</tt> means the type <tt>a</tt> belongs to the vector
--   space <tt>v n</tt>, where <tt>v</tt> is <a>Additive</a> and <tt>n</tt>
--   is a <a>Num</a>.
type InSpace (v :: Type -> Type) n a = (V a ~ v, N a ~ n, Additive v, Num n)

-- | <tt>SameSpace a b</tt> means the types <tt>a</tt> and <tt>b</tt>
--   belong to the same vector space <tt>v n</tt>.
type SameSpace a b = (V a ~ V b, N a ~ N b)

-- | A handy wrapper to help distinguish points from vectors at the type
--   level
data Point (f :: Type -> Type) a

-- | Vector spaces have origins.
origin :: forall (f :: Type -> Type) a. (Additive f, Num a) => Point f a

-- | Scale a point by a scalar. Specialized version of <a>(*^)</a>.
(*.) :: forall (v :: Type -> Type) n. (Functor v, Num n) => n -> Point v n -> Point v n

-- | An isomorphism between points and vectors, given a reference point.
relative :: forall (f :: Type -> Type) a. (Additive f, Num a) => Point f a -> Iso' (Point f a) (f a)

-- | Produce a default basis for a vector space. If the dimensionality of
--   the vector space is not statically known, see <a>basisFor</a>.
basis :: (Additive t, Traversable t, Num a) => [t a]

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

-- | The determinant of (the linear part of) a <a>Transformation</a>.
determinant :: forall (v :: Type -> Type) n. (Additive v, Traversable v, Num n) => Transformation v n -> n

-- | Determine whether a <a>Transformation</a> includes a reflection
--   component, that is, whether it reverses orientation.
isReflection :: forall (v :: Type -> Type) n. (Additive v, Traversable v, Num n, Ord n) => Transformation v n -> Bool

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

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

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

-- | Apply a linear map to a vector.
lapp :: (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. (For a more detailed explanation and proof, see
--   <a>https://wiki.haskell.org/Diagrams/Dev/Transformations</a>.) 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-invertible transformations, see
--   <tt>Diagrams.Deform</tt> (in <tt>diagrams-lib</tt>).
data Transformation (v :: Type -> Type) n

-- | Invert a transformation.
inv :: forall (v :: Type -> Type) n. (Functor v, Num n) => Transformation v n -> Transformation v n

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

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

-- | Drop the translational component of a transformation, leaving only the
--   linear part.
dropTransl :: forall (v :: Type -> Type) n. (Additive v, Num n) => Transformation v n -> Transformation v n

-- | 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 :: Transformation v n -> v n -> v n

-- | Apply a transformation to a point.
papply :: forall (v :: Type -> Type) n. (Additive v, Num n) => Transformation v n -> Point v n -> Point v n

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

-- | Create a translation.
translation :: v n -> Transformation v n

-- | Translate by a vector.
translate :: Transformable t => Vn 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 :: forall (v :: Type -> Type) n t. (InSpace v n t, HasOrigin t) => Point v n -> 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 :: forall (v :: Type -> Type) n t. (InSpace v n t, HasOrigin t) => t -> Point v n -> t

-- | Create a uniform scaling transformation.
scaling :: forall (v :: Type -> Type) n. (Additive v, Fractional n) => n -> Transformation v n

-- | Scale uniformly in every dimension by the given scalar.
scale :: forall (v :: Type -> Type) n a. (InSpace v n a, Eq n, Fractional n, Transformable a) => n -> a -> a

-- | Compute the "average" amount of scaling performed by a transformation.
--   Satisfies the properties
--   
--   <pre>
--   avgScale (scaling k) == k
--   avgScale (t1 &lt;&gt; t2)  == avgScale t1 * avgScale t2
--   
--   </pre>
avgScale :: forall (v :: Type -> Type) n. (Additive v, Traversable v, Floating n) => Transformation v n -> n

-- | Type class for things <tt>t</tt> which can be transformed.
class Transformable t

-- | Apply a transformation to an object.
transform :: Transformable t => Transformation (V t) (N 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

-- | Identity matrix.
eye :: (HasBasis v, Num n) => v (v n)

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

-- | Qualify with the given name.
(.>>) :: (Qualifiable q, IsName a) => a -> q -> q
infixr 5 .>>

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

-- | Traversal over each name in a <a>Name</a> that matches the target
--   type.
--   
--   <pre>
--   &gt;&gt;&gt; toListOf eachName (<tt>a</tt> .&gt; False .&gt; <tt>b</tt>) :: String
--   "ab"
--   &gt;&gt;&gt; <tt>a</tt> .&gt; True .&gt; <tt>b</tt> &amp; eachName %~ not
--   <tt>a</tt> .&gt; False .&gt; <tt>b</tt>
--   </pre>
--   
--   Note that the type of the name is very important.
--   
--   <pre>
--   &gt;&gt;&gt; sumOf eachName ((1::Int) .&gt; (2 :: Integer) .&gt; (3 :: Int)) :: Int
--   4
--   &gt;&gt;&gt; sumOf eachName ((1::Int) .&gt; (2 :: Integer) .&gt; (3 :: Int)) :: Integer
--   2
--   </pre>
eachName :: (Typeable a, Ord a, Show a) => Traversal' Name a

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

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

-- | Add a name/diagram association to a submap.
rememberAs :: forall a b (v :: Type -> Type) n m. IsName a => a -> QDiagram b v n m -> SubMap b v n m -> SubMap b v n 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 :: forall nm b (v :: Type -> Type) n m. IsName nm => nm -> SubMap b v n m -> Maybe [Subdiagram b v n 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 :: Type -> Type) n
[Attribute] :: forall a (v :: Type -> Type) n. AttributeClass a => a -> Attribute v n
[MAttribute] :: forall a n (v :: Type -> Type). AttributeClass a => Measured n a -> Attribute v n
[TAttribute] :: forall a (v :: Type -> Type) n. (AttributeClass a, Transformable a, V a ~ v, N a ~ n) => a -> Attribute v n

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

-- | Type class for things which have a style.
class HasStyle a

-- | <i>Apply</i> a style by combining it (on the left) with the existing
--   style.
applyStyle :: HasStyle a => Style (V a) (N 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.
--   
--   Trying to extract a measured attibute will fail. It either has to be
--   unmeasured with <a>unmeasureAttrs</a> or use the <a>atMAttr</a> lens.
getAttr :: forall a (v :: Type -> Type) n. AttributeClass a => Style v n -> Maybe a

-- | Lens onto a plain attribute of a style.
atAttr :: forall a (v :: Type -> Type) n. AttributeClass a => Lens' (Style v n) (Maybe a)

-- | Lens onto a measured attribute of a style.
atMAttr :: forall a n (v :: Type -> Type). (AttributeClass a, Typeable n) => Lens' (Style v n) (Maybe (Measured n a))

-- | Lens onto a transformable attribute of a style.
atTAttr :: forall a (v :: Type -> Type) n. (V a ~ v, N a ~ n, AttributeClass a, Transformable a) => Lens' (Style v n) (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 measured 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.
applyMAttr :: (AttributeClass a, N d ~ n, HasStyle d) => Measured n 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, N a ~ N 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://ozark.hendrix.edu/~yorgey/pub/monoid-pearl.pdf</a>; video:
--   <a>http://www.youtube.com/watch?v=X-8NCkD2vOw</a>.
newtype Envelope (v :: Type -> Type) n
Envelope :: Maybe (v n -> Max n) -> Envelope (v :: Type -> Type) n

-- | "Apply" an envelope by turning it into a function. <tt>Nothing</tt> is
--   returned iff the envelope is empty.
appEnvelope :: Envelope v n -> Maybe (v n -> n)

-- | A convenient way to transform an envelope, by specifying a
--   transformation on the underlying <tt>v n -&gt; n</tt> function. The
--   empty envelope is unaffected.
onEnvelope :: ((v n -> n) -> v n -> n) -> Envelope v n -> Envelope v n

-- | Create an envelope from a <tt>v n -&gt; n</tt> function.
mkEnvelope :: (v n -> n) -> Envelope v n

-- | <tt>Enveloped</tt> abstracts over things which have an envelope.
class (Metric V a, OrderedField N a) => Enveloped a

-- | Compute the envelope of an object. For types with an intrinsic notion
--   of "local origin", the envelope will be based there. Other types (e.g.
--   <tt>Trail</tt>) may have some other default reference point at which
--   the envelope will be based; their instances should document what it
--   is.
getEnvelope :: Enveloped a => a -> Envelope (V a) (N 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 => Vn a -> a -> Maybe (Vn 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 => Vn a -> a -> Vn a

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

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

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

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

-- | The smallest positive <i>axis-parallel</i> vector that bounds the
--   envelope of an object.
size :: (V a ~ v, N a ~ n, Enveloped a, HasBasis v) => a -> v n

-- | 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 :: Type -> Type) n
Trace :: (Point v n -> v n -> SortedList n) -> Trace (v :: Type -> Type) n

-- | 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]
appTrace :: Trace v n -> Point v n -> v n -> SortedList n
mkTrace :: (Point v n -> v n -> SortedList n) -> Trace v n

-- | <tt>Traced</tt> abstracts over things which have a trace.
class (Additive V a, Ord N a) => Traced a

-- | Compute the trace of an object.
getTrace :: Traced a => a -> Trace (V a) (N 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 :: (n ~ N a, Num n, Traced a) => Point (V a) n -> V a n -> a -> Maybe (V a n)

-- | 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 :: (n ~ N a, Traced a, Num n) => Point (V a) n -> V a n -> a -> Maybe (Point (V a) n)

-- | 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 :: (n ~ N a, Num n, Traced a) => Point (V a) n -> V a n -> a -> Maybe (V a n)

-- | 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 :: (n ~ N a, Num n, Traced a) => Point (V a) n -> V a n -> a -> Maybe (Point (V a) n)

-- | 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 :: (n ~ N a, Traced a, Num n) => Point (V a) n -> V a n -> a -> Maybe (V a n)

-- | 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 :: (n ~ N a, Traced a, Num n) => Point (V a) n -> V a n -> a -> Maybe (Point (V a) n)

-- | 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 :: (n ~ N a, Traced a, Num n) => Point (V a) n -> V a n -> a -> Maybe (V a n)

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

-- | 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 (negated 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 HasOrigin t

-- | Move the local origin to another point.
--   
--   Note that this function is in some sense dual to <tt>translate</tt>
--   (for types which are also <tt>Transformable</tt>); moving the origin
--   itself while leaving the object "fixed" is dual to fixing the origin
--   and translating the diagram.
moveOriginTo :: HasOrigin t => Point (V t) (N t) -> t -> t

-- | Move the local origin by a relative vector.
moveOriginBy :: (V t ~ v, N t ~ n, HasOrigin t) => v n -> t -> t

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

-- | <tt>juxtapose v a1 a2</tt> positions <tt>a2</tt> next to <tt>a1</tt>
--   in the direction of <tt>v</tt>. In particular, place <tt>a2</tt> so
--   that <tt>v</tt> points from the local origin of <tt>a1</tt> towards
--   the old local origin of <tt>a2</tt>; <tt>a1</tt>'s local origin
--   becomes <tt>a2</tt>'s new local origin. The result is just a
--   translated version of <tt>a2</tt>. (In particular, this operation does
--   not <i>combine</i> <tt>a1</tt> and <tt>a2</tt> in any way.)
juxtapose :: Juxtaposable a => Vn 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) => Vn 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 :: Type -> Type) n m
Query :: (Point v n -> m) -> Query (v :: Type -> Type) n m
[runQuery] :: Query (v :: Type -> Type) n m -> Point v n -> m

-- | A value of type <tt>Prim b v n</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 :: Type -> Type) n
[Prim] :: forall p b. (Transformable p, Typeable p, Renderable p b) => p -> Prim b (V p) (N 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>V2</tt> (for a two-dimensional diagram) or
--   <tt>V3</tt> (for a three-dimensional diagram).</li>
--   <li><tt>n</tt> represents the numerical field the diagram uses.
--   Typically this will be a concrete numeric type like
--   <tt>Double</tt>.</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 :: Type -> Type) n m

-- | <tt>Diagram b</tt> is a synonym for <tt><a>QDiagram</a> b (V b) (N b)
--   <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 v n</tt> or the <tt>value</tt> function.
type Diagram b = QDiagram b V b N b Any

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

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

-- | Lens onto the <a>Envelope</a> of a <a>QDiagram</a>.
envelope :: forall n (v :: Type -> Type) m b. (OrderedField n, Metric v, Monoid' m) => Lens' (QDiagram b v n m) (Envelope v n)

-- | Lens onto the <a>Trace</a> of a <a>QDiagram</a>.
trace :: forall (v :: Type -> Type) n m b. (Metric v, OrderedField n, Semigroup m) => Lens' (QDiagram b v n m) (Trace v n)

-- | Lens onto the <a>SubMap</a> of a <a>QDiagram</a> (<i>i.e.</i> an
--   association from names to subdiagrams).
subMap :: forall (v :: Type -> Type) m n b. (Metric v, Semigroup m, OrderedField n) => Lens' (QDiagram b v n m) (SubMap b v n m)

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

-- | Get the query function associated with a diagram.
query :: forall m b (v :: Type -> Type) n. Monoid m => QDiagram b v n m -> Query v n 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 :: forall nm (v :: Type -> Type) n m b. (IsName nm, Metric v, OrderedField n, Semigroup m) => (QDiagram b v n m -> Subdiagram b v n m) -> nm -> QDiagram b v n m -> QDiagram b v n 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 :: forall nm (v :: Type -> Type) m n b. (IsName nm, Metric v, Semigroup m, OrderedField n) => nm -> (Subdiagram b v n m -> QDiagram b v n m -> QDiagram b v n m) -> QDiagram b v n m -> QDiagram b v n 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 :: forall nm (v :: Type -> Type) m n b. (IsName nm, Metric v, Semigroup m, OrderedField n) => nm -> ([Subdiagram b v n m] -> QDiagram b v n m -> QDiagram b v n m) -> QDiagram b v n m -> QDiagram b v n 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 :: forall nm (v :: Type -> Type) m n b. (IsName nm, Metric v, Semigroup m, OrderedField n) => [nm] -> ([Subdiagram b v n m] -> QDiagram b v n m -> QDiagram b v n m) -> QDiagram b v n m -> QDiagram b v n m

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

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

-- | Change the transparency of a <a>Diagram</a> as a group.
opacityGroup :: forall (v :: Type -> Type) n m b. (Metric v, OrderedField n, Semigroup m) => Double -> QDiagram b v n m -> QDiagram b v n m

-- | Change the transparency of a <a>Diagram</a> as a group.
groupOpacity :: forall (v :: Type -> Type) n m b. (Metric v, OrderedField n, Semigroup m) => Double -> QDiagram b v n m -> QDiagram b v n m

-- | Replace the envelope of a diagram.
setEnvelope :: forall b (v :: Type -> Type) n m. (OrderedField n, Metric v, Monoid' m) => Envelope v n -> QDiagram b v n m -> QDiagram b v n m

-- | Replace the trace of a diagram.
setTrace :: forall b (v :: Type -> Type) n m. (OrderedField n, Metric v, Semigroup m) => Trace v n -> QDiagram b v n m -> QDiagram b v n 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 :: forall n (v :: Type -> Type) m b. (OrderedField n, Metric v, Semigroup m) => QDiagram b v n m -> QDiagram b v n m -> QDiagram b v n m
infixl 6 `atop`

-- | 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 :: Type -> Type) n m
Subdiagram :: QDiagram b v n m -> DownAnnots v n -> Subdiagram b (v :: Type -> Type) n m

-- | Turn a diagram into a subdiagram with no accumulated context.
mkSubdiagram :: forall b (v :: Type -> Type) n m. QDiagram b v n m -> Subdiagram b v n 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 :: forall (v :: Type -> Type) n m b. (Metric v, OrderedField n, Semigroup m) => Subdiagram b v n m -> QDiagram b v n m

-- | Extract the "raw" content of a subdiagram, by throwing away the
--   context.
rawSub :: forall b (v :: Type -> Type) n m. Subdiagram b v n m -> QDiagram b v n 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 :: forall (v :: Type -> Type) n b m. (Additive v, Num n) => Subdiagram b v n m -> Point v n

-- | 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 :: forall (v :: Type -> Type) n b m. (Metric v, OrderedField n) => Point v n -> Subdiagram b v n m

-- | 'Measured n a' is an object that depends on <a>local</a>,
--   <a>normalized</a> and <a>global</a> scales. The <a>normalized</a> and
--   <a>global</a> scales are calculated when rendering a diagram.
--   
--   For attributes, the <a>local</a> scale gets multiplied by the average
--   scale of the transform.
data Measured n a

-- | A measure is a <a>Measured</a> number.
type Measure n = Measured n n

-- | <pre>
--   fromMeasured globalScale normalizedScale measure -&gt; a
--   </pre>
fromMeasured :: Num n => n -> n -> Measured n a -> a

-- | Output units don't change.
output :: n -> Measure n

-- | Local units are scaled by the average scale of a transform.
local :: Num n => n -> Measure n

-- | Global units are scaled so that they are interpreted relative to the
--   size of the final rendered diagram.
global :: Num n => n -> Measure n

-- | Normalized units get scaled so that one normalized unit is the size of
--   the final diagram.
normalized :: Num n => n -> Measure n

-- | Scale the local units of a <a>Measured</a> thing.
scaleLocal :: Num n => n -> Measured n a -> Measured n a

-- | Calculate the larger of two measures.
atLeast :: Ord n => Measure n -> Measure n -> Measure n

-- | Calculate the smaller of two measures.
atMost :: Ord n => Measure n -> Measure n -> Measure n

-- | 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 Backend b (v :: Type -> Type) n where {
    
    -- | An intermediate representation used for rendering primitives.
    --   (Typically, this will be some sort of monad, but it need not be.) The
    --   <a>Renderable</a> class guarantees that a backend will be able to
    --   convert primitives into this type; how these rendered primitives are
    --   combined into an ultimate <a>Result</a> is completely up to the
    --   backend.
    data Render b (v :: Type -> Type) n;
    
    -- | The result of running/interpreting a rendering operation.
    type Result b (v :: Type -> Type) n;
    
    -- | Backend-specific rendering options.
    data Options b (v :: Type -> Type) n;
}

-- | <a>adjustDia</a> allows the backend to make adjustments to the final
--   diagram (e.g. to adjust the size based on the options) before
--   rendering it. It returns a modified options record, the transformation
--   applied to the diagram (which can be used to convert attributes whose
--   value is <tt>Measure</tt>, or transform <i>e.g.</i> screen coordinates
--   back into local diagram coordinates), and the adjusted diagram itself.
--   
--   See the diagrams-lib package (particularly the
--   <tt>Diagrams.TwoD.Adjust</tt> module) for some useful implementations.
adjustDia :: (Backend b v n, Additive v, Monoid' m, Num n) => b -> Options b v n -> QDiagram b v n m -> (Options b v n, Transformation v n, QDiagram b v n m)

-- | Given some options, take a representation of a diagram as a tree and
--   render it. The <a>RTree</a> has already been simplified and has all
--   measurements converted to <tt>Output</tt> units.
renderRTree :: Backend b v n => b -> Options b v n -> RTree b v n Annotation -> Result b v n

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

-- | Given a token representing the backend and a transformable object,
--   render it in the appropriate rendering context.
render :: Renderable t b => b -> t -> Render b (V t) (N t)

-- | Render a diagram.
renderDia :: forall b (v :: Type -> Type) n m. (Backend b v n, HasLinearMap v, Metric v, Typeable n, OrderedField n, Monoid' m) => b -> Options b v n -> QDiagram b v n m -> Result b v n

-- | 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 :: forall b (v :: Type -> Type) n m. (Backend b v n, HasLinearMap v, Metric v, Typeable n, OrderedField n, Monoid' m) => b -> Options b v n -> QDiagram b v n m -> (Transformation v n, Result b v n)

-- | 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 (uncheckedImageRef "foo.png" 200 200))
--   &lt;interactive&gt;:11:8:
--       No instance for (Renderable (DImage n0 External) b0)
--         arising from a use of <tt>image</tt>
--       The type variables <tt>n0</tt>, <tt>b0</tt> are ambiguous
--       Possible fix: add a type signature that fixes these type variable(s)
--       Note: there is a potential instance available:
--         instance Fractional n =&gt; Renderable (DImage n a) NullBackend
--           -- Defined in <a>Image</a>
--       Possible fix:
--         add an instance declaration for
--         (Renderable (DImage n0 External) b0)
--       In the first argument of <tt>width</tt>, namely
--         `(image (uncheckedImageRef "foo.png" 200 200))'
--       In the expression:
--         width (image (uncheckedImageRef "foo.png" 200 200))
--       In an equation for <tt>it</tt>:
--           it = width (image (uncheckedImageRef "foo.png" 200 200))
--   
--   </pre>
--   
--   GHC complains that there is no instance for <tt>Renderable (DImage n0
--   External) 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>n0</tt> and <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>V2</tt> <a>Double</a></tt>, like so:
--   
--   <pre>
--   ghci&gt; width (image (uncheckedImageRef "foo.png" 200 200) :: D V2 Double)
--   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;:12:1:
--       Couldn't match expected type <tt>V2</tt> with actual type `V a0'
--       The type variable <tt>a0</tt> is ambiguous
--       Possible fix: add a type signature that fixes these type variable(s)
--       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>TrailLike</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 V2 Double)
--   1.9999999999999998
--   
--   </pre>
type D (v :: Type -> Type) n = QDiagram NullBackend v n Any

-- | <a>HasLinearMap</a> is a constraint synonym, just to help shorten some
--   of the ridiculously long constraint sets.
type HasLinearMap (v :: Type -> Type) = (HasBasis v, Traversable v)

-- | An <a>Additive</a> vector space whose representation is made up of
--   basis elements.
type HasBasis (v :: Type -> Type) = (Additive v, Representable v, Rep v ~ E 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 constraint as a convenient shorthand.
type OrderedField s = (Floating s, Ord s)

-- | Constraint for numeric types that are <a>RealFloat</a> and
--   <a>Typeable</a>, which often occur together. This is used to shorten
--   shorten type constraint contexts.
type TypeableFloat n = (Typeable n, RealFloat n)

-- | For base &lt; 4.11, the <tt>Monoid'</tt> constraint is a synonym for
--   things which are instances of both <a>Semigroup</a> and <a>Monoid</a>.
--   For base version 4.11 and onwards, <tt>Monoid</tt> has
--   <tt>Semigroup</tt> as a superclass already, so for backwards
--   compatibility <tt>Monoid'</tt> is provided as a synonym for
--   <tt>Monoid</tt>.
type Monoid' = Monoid
