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


-- | 3d math including quaternions/euler angles/dcms and utility functions
--   
--   This is a port of my <a>mathlib</a> C library:
--   `https://github.com/ghorn/mathlib`
@package spatial-math
@version 0.5.0.1

module SpatialMath.Internal
libm_atan2 :: Double -> Double -> Double
libm_atan2f :: Float -> Float -> Float

module SpatialMath

-- | 3-2-1 Euler angle rotation sequence
data Euler a
Euler :: a -> a -> a -> Euler a
[eYaw] :: Euler a -> a
[ePitch] :: Euler a -> a
[eRoll] :: Euler a -> a

-- | doesn't require RealFloat, used for overloading symbolics
class Floating a => ArcTan2 a

-- | <tt>arctan2 y x</tt> computes the arctangent from two arguments. The
--   <a>Double</a> and <a>Float</a> instances call out to a sufficiently
--   recent version of <tt>libm</tt> to compute this.
--   
--   The following test cases are the <i>full</i> set of recommended
--   function properties specified for function <tt>atan2Pi()</tt> on page
--   45 of the IEEE Std 754-2008 document.
--   
--   <pre>
--   &gt;&gt;&gt; arctan2 0 (-0) :: Double
--   3.141592653589793
--   
--   &gt;&gt;&gt; arctan2 (-0) (-0) :: Double
--   -3.141592653589793
--   
--   &gt;&gt;&gt; arctan2 0 0 :: Double
--   0.0
--   
--   &gt;&gt;&gt; arctan2 (-0) 0 :: Double
--   -0.0
--   </pre>
--   
--   <pre>
--   \x -&gt; x &lt; 0 ==&gt; arctan2 (-0) x == (-pi :: Double)
--   </pre>
--   
--   <pre>
--   \x -&gt; x &lt; 0 ==&gt; arctan2 0 x == (pi :: Double)
--   </pre>
--   
--   <pre>
--   \x -&gt; x &gt; 0 ==&gt; arctan2 (-0) x == (-0 :: Double)
--   </pre>
--   
--   <pre>
--   \x -&gt; x &gt; 0 ==&gt; arctan2 0 x == (0 :: Double)
--   </pre>
--   
--   <pre>
--   \y -&gt; y &lt; 0 ==&gt; arctan2 y (-0) == (-pi / 2 :: Double)
--   </pre>
--   
--   <pre>
--   \y -&gt; y &gt; 0 ==&gt; arctan2 y 0 == (pi / 2 :: Double)
--   </pre>
--   
--   <pre>
--   \y -&gt; y &gt; 0 &amp;&amp; not (isNaN y || isInfinite y) ==&gt; arctan2 y (negate $ 1/0) == (pi :: Double)
--   </pre>
--   
--   <pre>
--   \y -&gt; y &lt; 0 &amp;&amp; not (isNaN y || isInfinite y) ==&gt; arctan2 y (negate $ 1/0) == (-pi :: Double)
--   </pre>
--   
--   <pre>
--   \y -&gt; y &gt; 0 &amp;&amp; not (isNaN y || isInfinite y) ==&gt; arctan2 y (1/0) == (0 :: Double)
--   </pre>
--   
--   <pre>
--   \y -&gt; y &lt; 0 &amp;&amp; not (isNaN y || isInfinite y) ==&gt; arctan2 y (1/0) == (-0 :: Double)
--   </pre>
--   
--   <pre>
--   \x -&gt; not (isNaN x || isInfinite x) ==&gt; arctan2 (negate $ 1/0) x == (-pi/2 :: Double)
--   </pre>
--   
--   <pre>
--   \x -&gt; not (isNaN x || isInfinite x) ==&gt; arctan2 (1/0) x == (pi/2 :: Double)
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; arctan2 neginf neginf :: Double
--   -2.356194490192345
--   
--   &gt;&gt;&gt; arctan2 inf neginf :: Double
--   2.356194490192345
--   
--   &gt;&gt;&gt; arctan2 neginf inf :: Double
--   -0.7853981633974483
--   
--   &gt;&gt;&gt; arctan2 inf inf :: Double
--   0.7853981633974483
--   </pre>
arctan2 :: ArcTan2 a => a -> a -> a

-- | Rotate a vector about the X axis
--   
--   <pre>
--   &gt;&gt;&gt; trunc $ rotateXyzAboutX (V3 0 1 0) (pi/2)
--   V3 0.0 0.0 1.0
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; trunc $ rotateXyzAboutX (V3 0 0 1) (pi/2)
--   V3 0.0 (-1.0) 0.0
--   </pre>
rotateXyzAboutX :: Floating a => V3 a -> a -> V3 a

-- | Rotate a vector about the Y axis
--   
--   <pre>
--   &gt;&gt;&gt; trunc $ rotateXyzAboutY (V3 0 0 1) (pi/2)
--   V3 1.0 0.0 0.0
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; trunc $ rotateXyzAboutY (V3 1 0 0) (pi/2)
--   V3 0.0 0.0 (-1.0)
--   </pre>
rotateXyzAboutY :: Floating a => V3 a -> a -> V3 a

-- | Rotate a vector about the Z axis
--   
--   <pre>
--   &gt;&gt;&gt; trunc $ rotateXyzAboutZ (V3 1 0 0) (pi/2)
--   V3 0.0 1.0 0.0
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; trunc $ rotateXyzAboutZ (V3 0 1 0) (pi/2)
--   V3 (-1.0) 0.0 0.0
--   </pre>
rotateXyzAboutZ :: Floating a => V3 a -> a -> V3 a

-- | Convert quaternion to Euler angles
--   
--   <pre>
--   &gt;&gt;&gt; euler321OfQuat (Quaternion 1.0 (V3 0.0 0.0 0.0))
--   Euler {eYaw = 0.0, ePitch = -0.0, eRoll = 0.0}
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; euler321OfQuat (Quaternion (sqrt(2)/2) (V3 (sqrt(2)/2) 0.0 0.0))
--   Euler {eYaw = 0.0, ePitch = -0.0, eRoll = 1.5707963267948966}
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; euler321OfQuat (Quaternion (sqrt(2)/2) (V3 0.0 (sqrt(2)/2) 0.0))
--   Euler {eYaw = 0.0, ePitch = 1.5707963267948966, eRoll = 0.0}
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; euler321OfQuat (Quaternion (sqrt(2)/2) (V3 0.0 0.0 (sqrt(2)/2)))
--   Euler {eYaw = 1.5707963267948966, ePitch = -0.0, eRoll = 0.0}
--   </pre>
euler321OfQuat :: (ArcTan2 a, Ord a) => Quaternion a -> Euler a

-- | Convert quaternion to Euler angles. Returns Nan if 2.0*(q1*q3 - q0*q2)
--   is outside [-1, 1].
--   
--   <pre>
--   &gt;&gt;&gt; unsafeEuler321OfQuat (Quaternion 1.0 (V3 0.0 0.0 0.0))
--   Euler {eYaw = 0.0, ePitch = -0.0, eRoll = 0.0}
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; unsafeEuler321OfQuat (Quaternion (sqrt(2)/2) (V3 (sqrt(2)/2) 0.0 0.0))
--   Euler {eYaw = 0.0, ePitch = -0.0, eRoll = 1.5707963267948966}
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; unsafeEuler321OfQuat (Quaternion (sqrt(2)/2) (V3 0.0 (sqrt(2)/2) 0.0))
--   Euler {eYaw = 0.0, ePitch = NaN, eRoll = 0.0}
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; unsafeEuler321OfQuat (Quaternion (sqrt(2)/2) (V3 0.0 0.0 (sqrt(2)/2)))
--   Euler {eYaw = 1.5707963267948966, ePitch = -0.0, eRoll = 0.0}
--   </pre>
unsafeEuler321OfQuat :: ArcTan2 a => Quaternion a -> Euler a

-- | Convert DCM to euler angles
--   
--   <pre>
--   &gt;&gt;&gt; euler321OfDcm $ V3 (V3 1 0 0) (V3 0 1 0) (V3 0 0 1)
--   Euler {eYaw = 0.0, ePitch = -0.0, eRoll = 0.0}
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; euler321OfDcm $ V3 (V3 0 1 0) (V3 (-1) 0 0) (V3 0 0 1)
--   Euler {eYaw = 1.5707963267948966, ePitch = -0.0, eRoll = 0.0}
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; let s = sqrt(2)/2 in euler321OfDcm $ V3 (V3 s s 0) (V3 (-s) s 0) (V3 0 0 1)
--   Euler {eYaw = 0.7853981633974483, ePitch = -0.0, eRoll = 0.0}
--   </pre>
euler321OfDcm :: (Ord a, ArcTan2 a) => M33 a -> Euler a

-- | Convert DCM to euler angles. Returns Nan if r[1,3] is outside [-1, 1].
--   
--   <pre>
--   &gt;&gt;&gt; unsafeEuler321OfDcm $ V3 (V3 1 0 0) (V3 0 1 0) (V3 0 0 1)
--   Euler {eYaw = 0.0, ePitch = -0.0, eRoll = 0.0}
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; unsafeEuler321OfDcm $ V3 (V3 0 1 0) (V3 (-1) 0 0) (V3 0 0 1)
--   Euler {eYaw = 1.5707963267948966, ePitch = -0.0, eRoll = 0.0}
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; let s = sqrt(2)/2 in unsafeEuler321OfDcm $ V3 (V3 s s 0) (V3 (-s) s 0) (V3 0 0 1)
--   Euler {eYaw = 0.7853981633974483, ePitch = -0.0, eRoll = 0.0}
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; unsafeEuler321OfDcm $ V3 (V3 0 0 1.1) (V3 0 0 0) (V3 0 0 0)
--   Euler {eYaw = 0.0, ePitch = NaN, eRoll = 0.0}
--   </pre>
unsafeEuler321OfDcm :: ArcTan2 a => M33 a -> Euler a

-- | Convert Euler angles to quaternion. The scalar part of the result may
--   be positive or negative.
--   
--   <pre>
--   &gt;&gt;&gt; quatOfEuler321 (Euler 0 0 0)
--   Quaternion 1.0 (V3 0.0 0.0 0.0)
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; quatOfEuler321 (Euler (pi/2) 0 0)
--   Quaternion 0.7071067811865476 (V3 0.0 0.0 0.7071067811865475)
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; quatOfEuler321 (Euler 0 (pi/2) 0)
--   Quaternion 0.7071067811865476 (V3 0.0 0.7071067811865475 0.0)
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; quatOfEuler321 (Euler 0 0 (pi/2))
--   Quaternion 0.7071067811865476 (V3 0.7071067811865475 0.0 0.0)
--   </pre>
quatOfEuler321 :: Floating a => Euler a -> Quaternion a

-- | convert a quaternion to a DCM
--   
--   <pre>
--   &gt;&gt;&gt; dcmOfQuat $ Quaternion 1.0 (V3 0.0 0.0 0.0)
--   V3 (V3 1.0 0.0 0.0) (V3 0.0 1.0 0.0) (V3 0.0 0.0 1.0)
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; let s = sqrt(2)/2 in fmap trunc $ dcmOfQuat $ Quaternion s (V3 0.0 0.0 s)
--   V3 (V3 0.0 1.0 0.0) (V3 (-1.0) 0.0 0.0) (V3 0.0 0.0 1.0)
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; dcmOfQuat $ Quaternion 0.9238795325112867 (V3 0.0 0.0 0.3826834323650898)
--   V3 (V3 0.7071067811865475 0.7071067811865476 0.0) (V3 (-0.7071067811865476) 0.7071067811865475 0.0) (V3 0.0 0.0 1.0)
--   </pre>
dcmOfQuat :: Num a => Quaternion a -> M33 a
dcmOfQuatB2A :: Num a => Quaternion a -> M33 a

-- | Convert DCM to euler angles
--   
--   <pre>
--   &gt;&gt;&gt; fmap trunc $ dcmOfEuler321 $ Euler {eYaw = 0.0, ePitch = 0, eRoll = 0}
--   V3 (V3 1.0 0.0 0.0) (V3 0.0 1.0 0.0) (V3 0.0 0.0 1.0)
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; fmap trunc $ dcmOfEuler321 $ Euler {eYaw = pi/2, ePitch = 0, eRoll = 0}
--   V3 (V3 0.0 1.0 0.0) (V3 (-1.0) 0.0 0.0) (V3 0.0 0.0 1.0)
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; fmap trunc $ dcmOfEuler321 $ Euler {eYaw = pi/4, ePitch = 0, eRoll = 0}
--   V3 (V3 0.7071067811865476 0.7071067811865475 0.0) (V3 (-0.7071067811865475) 0.7071067811865476 0.0) (V3 0.0 0.0 1.0)
--   </pre>
dcmOfEuler321 :: Floating a => Euler a -> M33 a

-- | convert a DCM to a quaternion
--   
--   <pre>
--   &gt;&gt;&gt; quatOfDcm $ V3 (V3 1 0 0) (V3 0 1 0) (V3 0 0 1)
--   Quaternion 1.0 (V3 0.0 0.0 0.0)
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; quatOfDcm $ V3 (V3 0 1 0) (V3 (-1) 0 0) (V3 0 0 1)
--   Quaternion 0.7071067811865476 (V3 0.0 0.0 0.7071067811865475)
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; let s = sqrt(2)/2 in quatOfDcm $ V3 (V3 s s 0) (V3 (-s) s 0) (V3 0 0 1)
--   Quaternion 0.9238795325112867 (V3 0.0 0.0 0.3826834323650898)
--   </pre>
quatOfDcm :: (Floating a, Ord a) => M33 a -> Quaternion a
quatOfDcmB2A :: (Floating a, Ord a) => M33 a -> Quaternion a

-- | vec_b = R_a2b * vec_a
rotVecByDcm :: Num a => M33 a -> V3 a -> V3 a

-- | vec_a = R_a2b^T * vec_b
rotVecByDcmB2A :: Num a => M33 a -> V3 a -> V3 a

-- | vec_b = q_a2b * vec_a * q_a2b^(-1) vec_b = R(q_a2b) * vec_a
rotVecByQuat :: Num a => Quaternion a -> V3 a -> V3 a
rotVecByQuatB2A :: Num a => Quaternion a -> V3 a -> V3 a
rotVecByEuler :: (Floating a, Ord a) => Euler a -> V3 a -> V3 a
rotVecByEulerB2A :: (Floating a, Ord a) => Euler a -> V3 a -> V3 a

-- | A 3x3 matrix with row-major representation
type M33 a = V3 V3 a

-- | A 3-dimensional vector
data V3 a
V3 :: !a -> !a -> !a -> V3 a

-- | Quaternions
data Quaternion a
Quaternion :: !a -> {-# UNPACK #-} !V3 a -> Quaternion a
instance SpatialMath.ArcTan2 GHC.Types.Double
instance SpatialMath.ArcTan2 GHC.Types.Float

module SpatialMathT

-- | doesn't require RealFloat, used for overloading symbolics
class Floating a => ArcTan2 a

-- | <tt>arctan2 y x</tt> computes the arctangent from two arguments. The
--   <a>Double</a> and <a>Float</a> instances call out to a sufficiently
--   recent version of <tt>libm</tt> to compute this.
--   
--   The following test cases are the <i>full</i> set of recommended
--   function properties specified for function <tt>atan2Pi()</tt> on page
--   45 of the IEEE Std 754-2008 document.
--   
--   <pre>
--   &gt;&gt;&gt; arctan2 0 (-0) :: Double
--   3.141592653589793
--   
--   &gt;&gt;&gt; arctan2 (-0) (-0) :: Double
--   -3.141592653589793
--   
--   &gt;&gt;&gt; arctan2 0 0 :: Double
--   0.0
--   
--   &gt;&gt;&gt; arctan2 (-0) 0 :: Double
--   -0.0
--   </pre>
--   
--   <pre>
--   \x -&gt; x &lt; 0 ==&gt; arctan2 (-0) x == (-pi :: Double)
--   </pre>
--   
--   <pre>
--   \x -&gt; x &lt; 0 ==&gt; arctan2 0 x == (pi :: Double)
--   </pre>
--   
--   <pre>
--   \x -&gt; x &gt; 0 ==&gt; arctan2 (-0) x == (-0 :: Double)
--   </pre>
--   
--   <pre>
--   \x -&gt; x &gt; 0 ==&gt; arctan2 0 x == (0 :: Double)
--   </pre>
--   
--   <pre>
--   \y -&gt; y &lt; 0 ==&gt; arctan2 y (-0) == (-pi / 2 :: Double)
--   </pre>
--   
--   <pre>
--   \y -&gt; y &gt; 0 ==&gt; arctan2 y 0 == (pi / 2 :: Double)
--   </pre>
--   
--   <pre>
--   \y -&gt; y &gt; 0 &amp;&amp; not (isNaN y || isInfinite y) ==&gt; arctan2 y (negate $ 1/0) == (pi :: Double)
--   </pre>
--   
--   <pre>
--   \y -&gt; y &lt; 0 &amp;&amp; not (isNaN y || isInfinite y) ==&gt; arctan2 y (negate $ 1/0) == (-pi :: Double)
--   </pre>
--   
--   <pre>
--   \y -&gt; y &gt; 0 &amp;&amp; not (isNaN y || isInfinite y) ==&gt; arctan2 y (1/0) == (0 :: Double)
--   </pre>
--   
--   <pre>
--   \y -&gt; y &lt; 0 &amp;&amp; not (isNaN y || isInfinite y) ==&gt; arctan2 y (1/0) == (-0 :: Double)
--   </pre>
--   
--   <pre>
--   \x -&gt; not (isNaN x || isInfinite x) ==&gt; arctan2 (negate $ 1/0) x == (-pi/2 :: Double)
--   </pre>
--   
--   <pre>
--   \x -&gt; not (isNaN x || isInfinite x) ==&gt; arctan2 (1/0) x == (pi/2 :: Double)
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; arctan2 neginf neginf :: Double
--   -2.356194490192345
--   
--   &gt;&gt;&gt; arctan2 inf neginf :: Double
--   2.356194490192345
--   
--   &gt;&gt;&gt; arctan2 neginf inf :: Double
--   -0.7853981633974483
--   
--   &gt;&gt;&gt; arctan2 inf inf :: Double
--   0.7853981633974483
--   </pre>
arctan2 :: ArcTan2 a => a -> a -> a

-- | 3-2-1 Euler angle rotation sequence
data Euler a
Euler :: a -> a -> a -> Euler a
[eYaw] :: Euler a -> a
[ePitch] :: Euler a -> a
[eRoll] :: Euler a -> a

-- | Quaternions
data Quaternion a
Quaternion :: !a -> {-# UNPACK #-} !V3 a -> Quaternion a

-- | A 3-dimensional vector
data V3 a
V3 :: !a -> !a -> !a -> V3 a
class Rotation g a
compose :: Rotation g a => Rot f1 f2 g a -> Rot f2 f3 g a -> Rot f1 f3 g a
rot :: Rotation g a => Rot f1 f2 g a -> V3T f1 a -> V3T f2 a
rot' :: Rotation g a => Rot f1 f2 g a -> V3T f2 a -> V3T f1 a
transpose :: Rotation g a => Rot f1 f2 g a -> Rot f2 f1 g a
identity :: Rotation g a => Rot f1 f2 g a
newtype Rot f1 f2 r a
Rot :: r a -> Rot f1 f2 r a
[unRot] :: Rot f1 f2 r a -> r a
newtype V3T f a
V3T :: V3 a -> V3T f a
[unV] :: V3T f a -> V3 a

-- | A space that has at least 1 basis vector <a>_x</a>.
class R1 (t :: * -> *)

-- | <pre>
--   &gt;&gt;&gt; V1 2 ^._x
--   2
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; V1 2 &amp; _x .~ 3
--   V1 3
--   </pre>
_x :: (R1 t, Functor f) => a -> f a -> t a -> f t a

-- | A space that distinguishes 2 orthogonal basis vectors <a>_x</a> and
--   <a>_y</a>, but may have more.
class R1 t => R2 (t :: * -> *)

-- | <pre>
--   &gt;&gt;&gt; V2 1 2 ^._y
--   2
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; V2 1 2 &amp; _y .~ 3
--   V2 1 3
--   </pre>
_y :: (R2 t, Functor f) => a -> f a -> t a -> f t a
_xy :: (R2 t, Functor f) => V2 a -> f V2 a -> t a -> f t a

-- | A space that distinguishes 3 orthogonal basis vectors: <a>_x</a>,
--   <a>_y</a>, and <a>_z</a>. (It may have more)
class R2 t => R3 (t :: * -> *)

-- | <pre>
--   &gt;&gt;&gt; V3 1 2 3 ^. _z
--   3
--   </pre>
_z :: (R3 t, Functor f) => a -> f a -> t a -> f t a
_xyz :: (R3 t, Functor f) => V3 a -> f V3 a -> t a -> f t a
cross :: Num a => V3T f a -> V3T f a -> V3T f a
orthonormalize :: Floating a => Rot f1 f2 (V3 :. V3) a -> Rot f1 f2 (V3 :. V3) a
dcmOfQuat :: Num a => Rot f g Quaternion a -> Rot f g (V3 :. V3) a
dcmOfEuler321 :: Floating a => Rot f g Euler a -> Rot f g (V3 :. V3) a
quatOfDcm :: (Floating a, Ord a) => Rot f g (V3 :. V3) a -> Rot f g Quaternion a
quatOfEuler321 :: Floating a => Rot f g Euler a -> Rot f g Quaternion a
euler321OfDcm :: (ArcTan2 a, Ord a) => Rot f g (V3 :. V3) a -> Rot f g Euler a
unsafeEuler321OfDcm :: ArcTan2 a => Rot f g (V3 :. V3) a -> Rot f g Euler a
euler321OfQuat :: (ArcTan2 a, Ord a) => Rot f g Quaternion a -> Rot f g Euler a
unsafeEuler321OfQuat :: ArcTan2 a => Rot f g Quaternion a -> Rot f g Euler a

-- | Composition of unary type constructors
--   
--   There are (at least) two useful <a>Monoid</a> instances, so you'll
--   have to pick one and type-specialize it (filling in all or parts of
--   <tt>g</tt> and/or <tt>f</tt>).
--   
--   <pre>
--   -- standard Monoid instance for Applicative applied to Monoid
--   instance (Applicative (g :. f), Monoid a) =&gt; Monoid ((g :. f) a) where
--     { mempty = pure mempty; mappend = liftA2 mappend }
--   -- Especially handy when g is a Monoid_f.
--   instance Monoid (g (f a)) =&gt; Monoid ((g :. f) a) where
--     { mempty = O mempty; mappend = inO2 mappend }
--   </pre>
--   
--   Corresponding to the first and second definitions above,
--   
--   <pre>
--   instance (Applicative g, Monoid_f f) =&gt; Monoid_f (g :. f) where
--     { mempty_f = O (pure mempty_f); mappend_f = inO2 (liftA2 mappend_f) }
--   instance Monoid_f g =&gt; Monoid_f (g :. f) where
--     { mempty_f = O mempty_f; mappend_f = inO2 mappend_f }
--   </pre>
--   
--   Similarly, there are two useful <a>Functor</a> instances and two
--   useful <a>ContraFunctor</a> instances.
--   
--   <pre>
--   instance (      Functor g,       Functor f) =&gt; Functor (g :. f) where fmap = fmapFF
--   instance (ContraFunctor g, ContraFunctor f) =&gt; Functor (g :. f) where fmap = fmapCC
--   
--   instance (      Functor g, ContraFunctor f) =&gt; ContraFunctor (g :. f) where contraFmap = contraFmapFC
--   instance (ContraFunctor g,       Functor f) =&gt; ContraFunctor (g :. f) where contraFmap = contraFmapCF
--   </pre>
--   
--   However, it's such a bother to define the Functor instances per
--   composition type, I've left the fmapFF case in. If you want the fmapCC
--   one, you're out of luck for now. I'd love to hear a good solution.
--   Maybe someday Haskell will do Prolog-style search for instances,
--   subgoaling the constraints, rather than just matching instance heads.
newtype (:.) (g :: k2 -> *) (f :: k1 -> k2) (a :: k1) :: forall k2 k1. () => k2 -> * -> k1 -> k2 -> k1 -> *
O :: g f a -> (:.)

-- | Unwrap a '(:.)'.
unO :: () => g :. f a -> g f a
instance Data.Binary.Class.Binary (r a) => Data.Binary.Class.Binary (SpatialMathT.Rot f1 f2 r a)
instance Data.Serialize.Serialize (r a) => Data.Serialize.Serialize (SpatialMathT.Rot f1 f2 r a)
instance GHC.Generics.Generic (SpatialMathT.Rot f1 f2 r a)
instance GHC.Generics.Generic1 (SpatialMathT.Rot f1 f2 r)
instance GHC.Classes.Ord (r a) => GHC.Classes.Ord (SpatialMathT.Rot f1 f2 r a)
instance GHC.Show.Show (r a) => GHC.Show.Show (SpatialMathT.Rot f1 f2 r a)
instance GHC.Classes.Eq (r a) => GHC.Classes.Eq (SpatialMathT.Rot f1 f2 r a)
instance GHC.Real.Fractional (r a) => GHC.Real.Fractional (SpatialMathT.Rot f1 f2 r a)
instance GHC.Num.Num (r a) => GHC.Num.Num (SpatialMathT.Rot f1 f2 r a)
instance Foreign.Storable.Storable (r a) => Foreign.Storable.Storable (SpatialMathT.Rot f1 f2 r a)
instance GHC.Base.Applicative r => GHC.Base.Applicative (SpatialMathT.Rot f1 f2 r)
instance Data.Traversable.Traversable r => Data.Traversable.Traversable (SpatialMathT.Rot f1 f2 r)
instance Data.Foldable.Foldable r => Data.Foldable.Foldable (SpatialMathT.Rot f1 f2 r)
instance GHC.Base.Functor r => GHC.Base.Functor (SpatialMathT.Rot f1 f2 r)
instance Data.Binary.Class.Binary a => Data.Binary.Class.Binary (SpatialMathT.V3T f a)
instance Data.Serialize.Serialize a => Data.Serialize.Serialize (SpatialMathT.V3T f a)
instance GHC.Generics.Generic (SpatialMathT.V3T f a)
instance GHC.Generics.Generic1 (SpatialMathT.V3T f)
instance GHC.Classes.Ord a => GHC.Classes.Ord (SpatialMathT.V3T f a)
instance GHC.Show.Show a => GHC.Show.Show (SpatialMathT.V3T f a)
instance GHC.Classes.Eq a => GHC.Classes.Eq (SpatialMathT.V3T f a)
instance GHC.Real.Fractional a => GHC.Real.Fractional (SpatialMathT.V3T f a)
instance GHC.Num.Num a => GHC.Num.Num (SpatialMathT.V3T f a)
instance Foreign.Storable.Storable a => Foreign.Storable.Storable (SpatialMathT.V3T f a)
instance Linear.Metric.Metric (SpatialMathT.V3T f)
instance Linear.Vector.Additive (SpatialMathT.V3T f)
instance GHC.Base.Applicative (SpatialMathT.V3T f)
instance Data.Traversable.Traversable (SpatialMathT.V3T f)
instance Data.Foldable.Foldable (SpatialMathT.V3T f)
instance GHC.Base.Functor (SpatialMathT.V3T f)
instance GHC.Num.Num a => SpatialMathT.Rotation Linear.Quaternion.Quaternion a
instance GHC.Num.Num a => SpatialMathT.Rotation (Linear.V3.V3 Control.Compose.:. Linear.V3.V3) a
instance (SpatialMath.ArcTan2 a, GHC.Float.Floating a, GHC.Classes.Ord a) => SpatialMathT.Rotation Types.Euler a
instance Linear.V1.R1 (SpatialMathT.V3T f)
instance Linear.V2.R2 (SpatialMathT.V3T f)
instance Linear.V3.R3 (SpatialMathT.V3T f)
