diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,5 +1,18 @@
 # Changelog for geomancy
 
+## 0.2.4.0
+
+A bunch of experimental code to see what sticks.
+
++ Added `simple-affine-space` instances.
+  * The classes are re-exported from `Geomancy`, bringing stuff like `dot` and `normalize`.
++ Added `mono-traversable` instances and `Geomancy.Elementwise` wrapper.
++ Added `Point` wrapper and `PointN` aliases.
++ Added `Geomancy.Interpolate` with generic linear, quadratic and cubic functions.
+  - ⚠️ `VecN.lerp` has wrong (flipped) order of vector arguments. This is fixed in `linear`.
++ Added `Geomancy.Swizzle` overloaded labels.
++ Added `Geomancy.Gl.Funs` with kinda-GLSL math functions, appropriately overloaded.
+
 ## 0.2.3.0
 
 - Vec4 moved to ByteArray#.
diff --git a/geomancy.cabal b/geomancy.cabal
--- a/geomancy.cabal
+++ b/geomancy.cabal
@@ -4,10 +4,10 @@
 --
 -- see: https://github.com/sol/hpack
 --
--- hash: aa93c14151d6ba606892efc64f6795f6f0ec8ebfc5b9f24e104d5b4676cf8bb8
+-- hash: fc54cd138f65f7b0038538046c6910af0933e7579e48981ee1eddc21bfcb6682
 
 name:           geomancy
-version:        0.2.3.0
+version:        0.2.4.0
 synopsis:       Geometry and matrix manipulation
 description:    Sometimes it is unavoidable you have to do stuff on CPU.
                 Let's at least do it faster.
@@ -29,11 +29,16 @@
 library
   exposed-modules:
       Geomancy
+      Geomancy.Elementwise
+      Geomancy.Gl.Funs
+      Geomancy.Interpolate
       Geomancy.IVec2
       Geomancy.IVec3
       Geomancy.IVec4
       Geomancy.Mat4
+      Geomancy.Point
       Geomancy.Quaternion
+      Geomancy.Swizzle
       Geomancy.Transform
       Geomancy.Transform.Tree
       Geomancy.Tree
@@ -43,6 +48,7 @@
       Geomancy.Vec2
       Geomancy.Vec3
       Geomancy.Vec4
+      Geomancy.Vector
       Geomancy.Vulkan.Projection
       Geomancy.Vulkan.View
   other-modules:
@@ -56,6 +62,8 @@
       base >=4.7 && <5
     , containers
     , deepseq
+    , mono-traversable
+    , simple-affine-space
   default-language: Haskell2010
 
 test-suite geomancy-test
@@ -72,6 +80,7 @@
     , geomancy
     , hedgehog
     , linear
+    , simple-affine-space
   default-language: Haskell2010
 
 benchmark geomancy-bench
@@ -88,4 +97,5 @@
     , deepseq
     , geomancy
     , linear
+    , simple-affine-space
   default-language: Haskell2010
diff --git a/src/Geomancy.hs b/src/Geomancy.hs
--- a/src/Geomancy.hs
+++ b/src/Geomancy.hs
@@ -10,16 +10,20 @@
   , vec2
   , withVec2
   , pattern WithVec2
+  , Point2
 
   , Vec3
   , vec3
   , withVec3
   , pattern WithVec3
+  , Point3
+  , Point3P
 
   , Vec4
   , vec4
   , withVec4
   , pattern WithVec4
+  , Point4
 
   -- ** Signed / int32s
 
@@ -55,6 +59,10 @@
   , withUVec4
   , pattern WithUVec4
 
+  -- ** Generic maps
+
+  , Elementwise(..)
+
   -- * Matrices
 
   , Mat4
@@ -65,6 +73,15 @@
   , Quaternion
   , quaternion
   , withQuaternion
+
+  -- * Spaces
+
+  , Point(..)
+  , AffineSpace(..)
+  , VectorSpace(..)
+  , (^*)
+  , lerp
+  , quadrance
   ) where
 
 import Geomancy.Vec2 (Vec2, vec2, withVec2, pattern WithVec2)
@@ -79,7 +96,12 @@
 import Geomancy.UVec3 (UVec3, uvec3, withUVec3, pattern WithUVec3)
 import Geomancy.UVec4 (UVec4, uvec4, withUVec4, pattern WithUVec4)
 
+import Geomancy.Elementwise (Elementwise(..))
+
 import Geomancy.Mat4 (Mat4)
 import Geomancy.Transform (Transform(..))
 
 import Geomancy.Quaternion (Quaternion, quaternion, withQuaternion)
+
+import Geomancy.Point (AffineSpace(..), Point(..), Point2, Point3, Point3P, Point4)
+import Geomancy.Vector (VectorSpace(..), lerp, quadrance, (^*))
diff --git a/src/Geomancy/Elementwise.hs b/src/Geomancy/Elementwise.hs
new file mode 100644
--- /dev/null
+++ b/src/Geomancy/Elementwise.hs
@@ -0,0 +1,42 @@
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE DerivingStrategies #-}
+{-# LANGUAGE DefaultSignatures #-}
+
+module Geomancy.Elementwise
+  ( Elementwise(..)
+  , Element
+  ) where
+
+import Data.MonoTraversable (Element, MonoFunctor(..), MonoPointed(..))
+
+class Elementwise a where
+  epoint :: Element a -> a
+
+  default epoint :: MonoPointed a => Element a -> a
+  epoint = opoint
+
+  emap
+    :: (Element a -> Element a)
+    -> a -> a
+  default emap
+    :: MonoFunctor a
+    => (Element a -> Element a)
+    -> a -> a
+  emap = omap
+
+  emap2
+    :: (Element a -> Element a -> Element a)
+    -> a -> a -> a
+
+  emap3
+    :: (Element a -> Element a -> Element a -> Element a)
+    -> a -> a -> a -> a
+
+  emap4
+    :: (Element a -> Element a -> Element a -> Element a -> Element a)
+    -> a -> a -> a -> a -> a
+
+  emap5
+    :: (Element a -> Element a -> Element a -> Element a -> Element a -> Element a)
+    -> a -> a -> a -> a -> a -> a
diff --git a/src/Geomancy/Gl/Funs.hs b/src/Geomancy/Gl/Funs.hs
new file mode 100644
--- /dev/null
+++ b/src/Geomancy/Gl/Funs.hs
@@ -0,0 +1,174 @@
+{-# LANGUAGE BlockArguments #-}
+{-# LANGUAGE DefaultSignatures #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeApplications #-}
+{-# LANGUAGE TypeFamilies #-}
+
+module Geomancy.Gl.Funs
+  ( GlClamp(..)
+  , glSaturate
+
+  , GlStep(..)
+  , normRange
+  , smoothstepPoly
+  , smootherstepPoly
+
+  , GlNearest(..)
+  , glFract
+
+  , GlMod(..)
+  , GlModf(..)
+
+  , GlMix(..)
+  ) where
+
+import Geomancy.Elementwise (Element, Elementwise(..))
+import Geomancy.Interpolate (linear, linearE)
+
+class GlClamp edge a where
+  glMin :: a -> edge -> a
+  glMax :: a -> edge -> a
+  glClamp :: a -> edge -> edge -> a
+
+  glClamp x minVal = glMin (glMax x minVal)
+
+instance {-# OVERLAPS #-} GlClamp Float Float where
+  glMin = min
+  glMax = max
+
+instance (Element v ~ Float, Elementwise v) => GlClamp Float v where
+  {-# INLINE glMin #-}
+  glMin a b = emap2 glMin a (epoint b)
+
+  {-# INLINE glMax #-}
+  glMax a b = emap2 glMax a (epoint b)
+
+instance (Element v ~ Float, Elementwise v) => GlClamp v v where
+  {-# INLINE glMin #-}
+  glMin = emap2 glMin
+
+  {-# INLINE glMax #-}
+  glMax = emap2 glMax
+
+glSaturate :: forall a . (GlClamp a a, Num a) => a -> a
+glSaturate x = glClamp @a x 0 1
+
+class GlClamp edge a => GlStep edge a where
+  glStep :: edge -> a -> a
+  glSmoothstep :: edge -> edge -> a -> a
+  glSmootherstep :: edge -> edge -> a -> a
+
+instance (Element v ~ Float, Elementwise v) => GlStep Float v where
+  glStep edge = emap2 glStep (epoint edge)
+  glSmoothstep edge0 edge1 = emap3 glSmoothstep (epoint edge0) (epoint edge1)
+  glSmootherstep edge0 edge1 = emap3 glSmootherstep (epoint edge0) (epoint edge1)
+
+instance (Element v ~ Float, Elementwise v) => GlStep v v where
+  glStep = emap2 glStep
+  glSmoothstep = emap3 glSmoothstep
+  glSmootherstep = emap3 glSmootherstep
+
+instance {-# OVERLAPS #-} GlStep Float Float where
+  {-# INLINE glStep #-}
+  glStep edge x =
+    if x < edge then
+      0
+    else
+      1
+
+  glSmoothstep edge0 edge1 x =
+    smoothstepPoly . glSaturate $
+      normRange edge0 edge1 x
+
+  glSmootherstep edge0 edge1 x =
+    smootherstepPoly . glSaturate $
+      normRange edge0 edge1 x
+
+{-# INLINE normRange #-}
+normRange :: Fractional a => a -> a -> a -> a
+normRange edge0 edge1 x = (x - edge0) / (edge1 - edge0)
+
+{-# INLINE smoothstepPoly #-}
+smoothstepPoly :: Num a => a -> a
+smoothstepPoly t = t * t * (3 - 2 * t)
+
+{-# INLINE smootherstepPoly #-}
+smootherstepPoly :: Num a => a -> a
+smootherstepPoly t = t * t * t * (t * (t * 6 - 15) + 10)
+
+class GlNearest a where
+  glCeil  :: a -> a
+  glFloor :: a -> a
+  glRound :: a -> a
+  glTrunc :: a -> a
+
+  default glCeil :: (Elementwise a, Element a ~ Float) => a -> a
+  glCeil = emap glCeil
+
+  default glFloor :: (Elementwise a, Element a ~ Float) => a -> a
+  glFloor = emap glFloor
+
+  default glRound :: (Elementwise a, Element a ~ Float) => a -> a
+  glRound = emap glRound
+
+  default glTrunc :: (Elementwise a, Element a ~ Float) => a -> a
+  glTrunc = emap glTrunc
+
+instance GlNearest Float where
+  {-# INLINE glCeil #-}
+  glCeil  = fromInteger . ceiling
+
+  {-# INLINE glFloor #-}
+  glFloor = fromInteger . floor
+
+  {-# INLINE glRound #-}
+  glRound = fromInteger . round
+
+  {-# INLINE glTrunc #-}
+  glTrunc = fromInteger . truncate
+
+{-# INLINE glFract #-}
+glFract :: (Num a, GlNearest a) => a -> a
+glFract x = x - glFloor x
+
+class GlModf i f where
+  glModf :: f -> (i, f)
+
+instance GlModf Integer Float where
+  {-# INLINE glModf #-}
+  glModf x =
+    let
+      integral = floor x
+    in
+      (integral, x - fromIntegral integral)
+
+instance GlModf Float Float where
+  {-# INLINE glModf #-}
+  glModf x = (fromInteger i, f)
+    where
+      (i, f) = glModf x
+
+class GlMod x y where
+  glMod :: x -> y -> x
+
+instance GlMod Float Float where
+  {-# INLINE glMod #-}
+  glMod x y = x - y * glFloor (x / y)
+
+class GlMix alpha x where
+  glMix :: x -> x -> alpha -> x
+
+instance {-# OVERLAPS #-} GlMix Float Float where
+  {-# INLINE glMix #-}
+  glMix = linear
+
+instance (Element v ~ Float, Elementwise v) => GlMix Float v where
+  {-# INLINE glMix #-}
+  glMix a b t = linearE a b (epoint t)
+
+instance (Element v ~ Float, Elementwise v) => GlMix v v where
+  {-# INLINE glMix #-}
+  glMix = linearE
diff --git a/src/Geomancy/IVec2.hs b/src/Geomancy/IVec2.hs
--- a/src/Geomancy/IVec2.hs
+++ b/src/Geomancy/IVec2.hs
@@ -1,6 +1,7 @@
 {-# LANGUAGE BlockArguments #-}
 {-# LANGUAGE PatternSynonyms #-}
 {-# LANGUAGE ViewPatterns #-}
+{-# LANGUAGE TypeFamilies #-}
 
 -- | Specialized and inlined @V2 Int32@.
 
@@ -14,8 +15,11 @@
 
 import Control.DeepSeq (NFData(rnf))
 import Data.Int (Int32)
+import Data.MonoTraversable (Element, MonoFunctor(..), MonoPointed(..))
 import Foreign (Storable(..))
 
+import Geomancy.Elementwise (Elementwise(..))
+
 data IVec2 = IVec2
   {-# UNPACK #-} !Int32
   {-# UNPACK #-} !Int32
@@ -42,6 +46,57 @@
 
 instance NFData IVec2 where
   rnf IVec2{} = ()
+
+type instance Element IVec2 = Int32
+
+instance MonoFunctor IVec2 where
+  {-# INLINE omap #-}
+  omap f v =
+    withIVec2 v \x y ->
+      ivec2 (f x) (f y)
+
+instance MonoPointed IVec2 where
+  {-# INLINE opoint #-}
+  opoint x = ivec2 x x
+
+instance Elementwise IVec2 where
+  {-# INLINE emap2 #-}
+  emap2 f p0 p1 =
+    withIVec2 p0 \x0 y0 ->
+    withIVec2 p1 \x1 y1 ->
+      ivec2
+        (f x0 x1)
+        (f y0 y1)
+
+  {-# INLINE emap3 #-}
+  emap3 f p0 p1 p2 =
+    withIVec2 p0 \x0 y0 ->
+    withIVec2 p1 \x1 y1 ->
+    withIVec2 p2 \x2 y2 ->
+      ivec2
+        (f x0 x1 x2)
+        (f y0 y1 y2)
+
+  {-# INLINE emap4 #-}
+  emap4 f p0 p1 p2 p3 =
+    withIVec2 p0 \x0 y0 ->
+    withIVec2 p1 \x1 y1 ->
+    withIVec2 p2 \x2 y2 ->
+    withIVec2 p3 \x3 y3 ->
+      ivec2
+        (f x0 x1 x2 x3)
+        (f y0 y1 y2 y3)
+
+  {-# INLINE emap5 #-}
+  emap5 f p0 p1 p2 p3 p4 =
+    withIVec2 p0 \x0 y0 ->
+    withIVec2 p1 \x1 y1 ->
+    withIVec2 p2 \x2 y2 ->
+    withIVec2 p3 \x3 y3 ->
+    withIVec2 p4 \x4 y4 ->
+      ivec2
+        (f x0 x1 x2 x3 x4)
+        (f y0 y1 y2 y3 y4)
 
 -- XXX: That's one nasty instance...
 instance Num IVec2 where
diff --git a/src/Geomancy/IVec3.hs b/src/Geomancy/IVec3.hs
--- a/src/Geomancy/IVec3.hs
+++ b/src/Geomancy/IVec3.hs
@@ -1,6 +1,7 @@
 {-# LANGUAGE BlockArguments #-}
 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
 {-# LANGUAGE PatternSynonyms #-}
+{-# LANGUAGE TypeFamilies #-}
 {-# LANGUAGE ViewPatterns #-}
 
 -- | Specialized and inlined @V2 Int32@.
@@ -18,8 +19,11 @@
 
 import Control.DeepSeq (NFData(rnf))
 import Data.Int (Int32)
+import Data.MonoTraversable (Element, MonoFunctor(..), MonoPointed(..))
 import Foreign (Storable(..))
 
+import Geomancy.Elementwise (Elementwise(..))
+
 data IVec3 = IVec3
   {-# UNPACK #-} !Int32
   {-# UNPACK #-} !Int32
@@ -47,6 +51,60 @@
 
 instance NFData IVec3 where
   rnf IVec3{} = ()
+
+type instance Element IVec3 = Int32
+
+instance MonoFunctor IVec3 where
+  {-# INLINE omap #-}
+  omap f v =
+    withIVec3 v \x y z ->
+      ivec3 (f x) (f y) (f z)
+
+instance MonoPointed IVec3 where
+  opoint x = ivec3 x x x
+
+instance Elementwise IVec3 where
+  {-# INLINE emap2 #-}
+  emap2 f p0 p1 =
+    withIVec3 p0 \x0 y0 z0 ->
+    withIVec3 p1 \x1 y1 z1 ->
+      ivec3
+        (f x0 x1)
+        (f y0 y1)
+        (f z0 z1)
+
+  {-# INLINE emap3 #-}
+  emap3 f p0 p1 p2 =
+    withIVec3 p0 \x0 y0 z0 ->
+    withIVec3 p1 \x1 y1 z1 ->
+    withIVec3 p2 \x2 y2 z2 ->
+      ivec3
+        (f x0 x1 x2)
+        (f y0 y1 y2)
+        (f z0 z1 z2)
+
+  {-# INLINE emap4 #-}
+  emap4 f p0 p1 p2 p3 =
+    withIVec3 p0 \x0 y0 z0 ->
+    withIVec3 p1 \x1 y1 z1 ->
+    withIVec3 p2 \x2 y2 z2 ->
+    withIVec3 p3 \x3 y3 z3 ->
+      ivec3
+        (f x0 x1 x2 x3)
+        (f y0 y1 y2 y3)
+        (f z0 z1 z2 z3)
+
+  {-# INLINE emap5 #-}
+  emap5 f p0 p1 p2 p3 p4 =
+    withIVec3 p0 \x0 y0 z0 ->
+    withIVec3 p1 \x1 y1 z1 ->
+    withIVec3 p2 \x2 y2 z2 ->
+    withIVec3 p3 \x3 y3 z3 ->
+    withIVec3 p4 \x4 y4 z4 ->
+      ivec3
+        (f x0 x1 x2 x3 x4)
+        (f y0 y1 y2 y3 y4)
+        (f z0 z1 z2 z3 z4)
 
 -- XXX: That's another nasty instance...
 instance Num IVec3 where
diff --git a/src/Geomancy/IVec4.hs b/src/Geomancy/IVec4.hs
--- a/src/Geomancy/IVec4.hs
+++ b/src/Geomancy/IVec4.hs
@@ -1,5 +1,6 @@
 {-# LANGUAGE BlockArguments #-}
 {-# LANGUAGE PatternSynonyms #-}
+{-# LANGUAGE TypeFamilies #-}
 {-# LANGUAGE ViewPatterns #-}
 
 -- | Specialized and inlined @V2 Int32@.
@@ -14,8 +15,11 @@
 
 import Control.DeepSeq (NFData(rnf))
 import Data.Int (Int32)
+import Data.MonoTraversable (Element, MonoFunctor(..), MonoPointed(..))
 import Foreign (Storable(..))
 
+import Geomancy.Elementwise (Elementwise(..))
+
 data IVec4 = IVec4
   {-# UNPACK #-} !Int32
   {-# UNPACK #-} !Int32
@@ -44,6 +48,64 @@
 
 instance NFData IVec4 where
   rnf IVec4{} = ()
+
+type instance Element IVec4 = Int32
+
+instance MonoFunctor IVec4 where
+  {-# INLINE omap #-}
+  omap f v =
+    withIVec4 v \x y z w ->
+      ivec4 (f x) (f y) (f z) (f w)
+
+instance MonoPointed IVec4 where
+  opoint x = ivec4 x x x x
+
+instance Elementwise IVec4 where
+  {-# INLINE emap2 #-}
+  emap2 f p0 p1 =
+    withIVec4 p0 \x0 y0 z0 w0 ->
+    withIVec4 p1 \x1 y1 z1 w1 ->
+      ivec4
+        (f x0 x1)
+        (f y0 y1)
+        (f z0 z1)
+        (f w0 w1)
+
+  {-# INLINE emap3 #-}
+  emap3 f p0 p1 p2 =
+    withIVec4 p0 \x0 y0 z0 w0 ->
+    withIVec4 p1 \x1 y1 z1 w1 ->
+    withIVec4 p2 \x2 y2 z2 w2 ->
+      ivec4
+        (f x0 x1 x2)
+        (f y0 y1 y2)
+        (f z0 z1 z2)
+        (f w0 w1 w2)
+
+  {-# INLINE emap4 #-}
+  emap4 f p0 p1 p2 p3 =
+    withIVec4 p0 \x0 y0 z0 w0 ->
+    withIVec4 p1 \x1 y1 z1 w1 ->
+    withIVec4 p2 \x2 y2 z2 w2 ->
+    withIVec4 p3 \x3 y3 z3 w3 ->
+      ivec4
+        (f x0 x1 x2 x3)
+        (f y0 y1 y2 y3)
+        (f z0 z1 z2 z3)
+        (f w0 w1 w2 w3)
+
+  {-# INLINE emap5 #-}
+  emap5 f p0 p1 p2 p3 p4 =
+    withIVec4 p0 \x0 y0 z0 w0 ->
+    withIVec4 p1 \x1 y1 z1 w1 ->
+    withIVec4 p2 \x2 y2 z2 w2 ->
+    withIVec4 p3 \x3 y3 z3 w3 ->
+    withIVec4 p4 \x4 y4 z4 w4 ->
+      ivec4
+        (f x0 x1 x2 x3 x4)
+        (f y0 y1 y2 y3 y4)
+        (f z0 z1 z2 z3 z4)
+        (f w0 w1 w2 w3 w4)
 
 -- XXX: That's another nasty instance...
 instance Num IVec4 where
diff --git a/src/Geomancy/Interpolate.hs b/src/Geomancy/Interpolate.hs
new file mode 100644
--- /dev/null
+++ b/src/Geomancy/Interpolate.hs
@@ -0,0 +1,98 @@
+{-# LANGUAGE BlockArguments #-}
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE PolyKinds #-}
+
+module Geomancy.Interpolate
+  ( linear
+  , linearE
+  , b1
+
+  , quadratic
+  , quadraticE
+  , b2
+
+  , cubic
+  , cubicE
+  , b3
+  ) where
+
+import Data.VectorSpace (VectorSpace, (*^), (^+^))
+import Geomancy.Elementwise (Element, Elementwise(..))
+
+{-# INLINEABLE linear #-}
+linear :: VectorSpace v a => v -> v -> a -> v
+linear p0 p1 t =
+  b01 *^ p0 ^+^
+  b11 *^ p1
+  where
+    (b01, b11) = b1 t
+
+{-# INLINEABLE linearE #-}
+linearE :: (Elementwise v, Element v ~ Float) => v -> v -> v -> v
+linearE = emap3 linear
+
+{-# INLINE b1 #-}
+b1 :: Num b => b -> (b, b)
+b1 t =
+  ( 1 - t
+  , t
+  )
+
+{-# INLINEABLE quadratic #-}
+quadratic :: VectorSpace v a => v -> v -> v -> a -> v
+quadratic p0 p1 p2 t =
+  b02 *^ p0 ^+^
+  b12 *^ p1 ^+^
+  b22 *^ p2
+  where
+    (b02, b12, b22) = b2 t
+
+{-# INLINEABLE quadraticE #-}
+quadraticE :: (Elementwise v, Element v ~ Float) => v -> v -> v -> v -> v
+quadraticE = emap4 quadratic
+
+{-# INLINE b2 #-}
+b2 :: Num c => c -> (c, c, c)
+b2 t =
+  ( 1 -
+    2 * t +
+    t * t
+
+  , 2 * t -
+    2 * t * t
+
+  , t * t
+  )
+
+{-# INLINEABLE cubic #-}
+cubic :: VectorSpace v a => v -> v -> v -> v -> a -> v
+cubic p0 p1 p2 p3 t =
+  b03 *^ p0 ^+^
+  b13 *^ p1 ^+^
+  b23 *^ p2 ^+^
+  b33 *^ p3
+  where
+    (b03, b13, b23, b33) = b3 t
+
+{-# INLINEABLE cubicE #-}
+cubicE :: (Elementwise v, Element v ~ Float) => v -> v -> v -> v -> v -> v
+cubicE = emap5 cubic
+
+{-# INLINE b3 #-}
+b3 :: Num d => d -> (d, d, d, d)
+b3 t =
+  ( 1 - 3 * t +
+    3 * t * t -
+    t * t * t
+
+  , 3 * t -
+    6 * t * t +
+    3 * t * t * t
+
+  , 3 * t * t -
+    3 * t * t * t
+
+  , t * t * t
+  )
diff --git a/src/Geomancy/Point.hs b/src/Geomancy/Point.hs
new file mode 100644
--- /dev/null
+++ b/src/Geomancy/Point.hs
@@ -0,0 +1,72 @@
+{-# LANGUAGE DerivingStrategies #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE GeneralisedNewtypeDeriving #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE TypeFamilies #-}
+
+module Geomancy.Point
+  ( Point(..)
+
+  , Point2
+  , Point3
+  , Point3P
+  , Point4
+
+  , AffineSpace
+  , (AffineSpace..+^)
+  , (AffineSpace..-^)
+  , (AffineSpace..-.)
+
+  , qd
+  , distance
+  , lerp
+  ) where
+
+import Control.DeepSeq (NFData)
+import Data.AffineSpace (AffineSpace)
+import Data.MonoTraversable (Element, MonoFunctor(..), MonoPointed(..))
+import Foreign.Storable (Storable)
+import qualified Data.AffineSpace as AffineSpace
+
+import Geomancy.Elementwise (Elementwise(..))
+import Geomancy.Vec2 (Vec2)
+import Geomancy.Vec3 (Vec3, Packed)
+import Geomancy.Vec4 (Vec4)
+import Geomancy.Vector (VectorSpace(..))
+import qualified Geomancy.Vector as Vector
+
+newtype Point v = Point v
+  deriving stock (Eq, Ord, Show)
+  deriving newtype (NFData, Num, Fractional, MonoFunctor, MonoPointed, Elementwise, Storable)
+
+type instance Element (Point v) = Element v
+
+type Point2 = Point Vec2
+type Point3 = Point Vec3
+type Point3P = Point Packed
+type Point4 = Point Vec4
+
+instance VectorSpace v Float => AffineSpace (Point v) v Float where
+  origin = Point zeroVector
+
+  {-# INLINE (.+^) #-}
+  Point p .+^ v = Point (p ^+^ v)
+
+  {-# INLINE (.-^) #-}
+  Point p .-^ v = Point (p ^-^ v)
+
+  {-# INLINE (.-.) #-}
+  Point a .-. Point b = a ^-^ b
+
+{-# INLINE qd #-}
+qd :: VectorSpace v Float => Point v -> Point v -> Float
+qd a b = Vector.quadrance (a AffineSpace..-. b)
+
+{-# INLINE distance #-}
+distance :: VectorSpace v Float => Point v -> Point v -> Float
+distance a b = sqrt (qd a b)
+
+{-# INLINE lerp #-}
+lerp :: VectorSpace v Float => Point v -> Point v -> Float -> Point v
+lerp (Point a) (Point b) = Point . Vector.lerp a b
diff --git a/src/Geomancy/Swizzle.hs b/src/Geomancy/Swizzle.hs
new file mode 100644
--- /dev/null
+++ b/src/Geomancy/Swizzle.hs
@@ -0,0 +1,1513 @@
+{-# LANGUAGE BlockArguments #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE RankNTypes #-}
+
+module Geomancy.Swizzle
+  ( swizzle
+  , (.@)
+  ) where
+
+import GHC.OverloadedLabels
+
+import Geomancy.Vec2 (Vec2, vec2, withVec2)
+import Geomancy.Vec3 (Vec3, vec3, withVec3)
+import Geomancy.Vec4 (Vec4, vec4, withVec4)
+
+newtype Swizzle to fro = Swizzle { swizzle :: fro -> to }
+
+{-# INLINE (.@) #-}
+(.@) :: forall to fro . fro -> Swizzle to fro -> to
+v .@ Swizzle f = f v
+
+-- * From Vec2
+
+-- ** To Float
+
+instance IsLabel "x" (Swizzle Float Vec2) where
+  fromLabel = Swizzle \v -> withVec2 v \x _ -> x
+
+instance IsLabel "y" (Swizzle Float Vec2) where
+  fromLabel = Swizzle \v -> withVec2 v \_ y -> y
+
+-- ** To Vec2
+
+instance IsLabel "xx" (Swizzle Vec2 Vec2) where
+  fromLabel = Swizzle \v -> withVec2 v \x _ -> vec2 x x
+
+instance IsLabel "yx" (Swizzle Vec2 Vec2) where
+  fromLabel = Swizzle \v -> withVec2 v \x y -> vec2 y x
+
+instance IsLabel "yy" (Swizzle Vec2 Vec2) where
+  fromLabel = Swizzle \v -> withVec2 v \_ y -> vec2 y y
+
+-- ** To Vec3
+
+instance IsLabel "xxx" (Swizzle Vec3 Vec2) where
+  fromLabel = Swizzle \v -> withVec2 v \x _ -> vec3 x x x
+
+instance IsLabel "xxy" (Swizzle Vec3 Vec2) where
+  fromLabel = Swizzle \v -> withVec2 v \x y -> vec3 x x y
+
+instance IsLabel "xyx" (Swizzle Vec3 Vec2) where
+  fromLabel = Swizzle \v -> withVec2 v \x y -> vec3 x y x
+
+instance IsLabel "xyy" (Swizzle Vec3 Vec2) where
+  fromLabel = Swizzle \v -> withVec2 v \x y -> vec3 x y y
+
+instance IsLabel "yxx" (Swizzle Vec3 Vec2) where
+  fromLabel = Swizzle \v -> withVec2 v \x y -> vec3 y x x
+
+instance IsLabel "yxy" (Swizzle Vec3 Vec2) where
+  fromLabel = Swizzle \v -> withVec2 v \x y -> vec3 y x y
+
+instance IsLabel "yyx" (Swizzle Vec3 Vec2) where
+  fromLabel = Swizzle \v -> withVec2 v \x y -> vec3 y y x
+
+instance IsLabel "yyy" (Swizzle Vec3 Vec2) where
+  fromLabel = Swizzle \v -> withVec2 v \_ y -> vec3 y y y
+
+-- ** To Vec4
+
+instance IsLabel "xxxx" (Swizzle Vec4 Vec2) where
+  fromLabel = Swizzle \v -> withVec2 v \x _ -> vec4 x x x x
+
+instance IsLabel "xxxy" (Swizzle Vec4 Vec2) where
+  fromLabel = Swizzle \v -> withVec2 v \x y -> vec4 x x x y
+
+instance IsLabel "xxyx" (Swizzle Vec4 Vec2) where
+  fromLabel = Swizzle \v -> withVec2 v \x y -> vec4 x x y x
+
+instance IsLabel "xxyy" (Swizzle Vec4 Vec2) where
+  fromLabel = Swizzle \v -> withVec2 v \x y -> vec4 x x y y
+
+instance IsLabel "xyxx" (Swizzle Vec4 Vec2) where
+  fromLabel = Swizzle \v -> withVec2 v \x y -> vec4 x y x x
+
+instance IsLabel "xyxy" (Swizzle Vec4 Vec2) where
+  fromLabel = Swizzle \v -> withVec2 v \x y -> vec4 x y x y
+
+instance IsLabel "xyyx" (Swizzle Vec4 Vec2) where
+  fromLabel = Swizzle \v -> withVec2 v \x y -> vec4 x y y x
+
+instance IsLabel "xyyy" (Swizzle Vec4 Vec2) where
+  fromLabel = Swizzle \v -> withVec2 v \x y -> vec4 x y y y
+
+instance IsLabel "yxxx" (Swizzle Vec4 Vec2) where
+  fromLabel = Swizzle \v -> withVec2 v \x y -> vec4 y x x x
+
+instance IsLabel "yxxy" (Swizzle Vec4 Vec2) where
+  fromLabel = Swizzle \v -> withVec2 v \x y -> vec4 y x x y
+
+instance IsLabel "yxyx" (Swizzle Vec4 Vec2) where
+  fromLabel = Swizzle \v -> withVec2 v \x y -> vec4 y x y x
+
+instance IsLabel "yxyy" (Swizzle Vec4 Vec2) where
+  fromLabel = Swizzle \v -> withVec2 v \x y -> vec4 y x y y
+
+instance IsLabel "yyxx" (Swizzle Vec4 Vec2) where
+  fromLabel = Swizzle \v -> withVec2 v \x y -> vec4 y y x x
+
+instance IsLabel "yyxy" (Swizzle Vec4 Vec2) where
+  fromLabel = Swizzle \v -> withVec2 v \x y -> vec4 y y x y
+
+instance IsLabel "yyyx" (Swizzle Vec4 Vec2) where
+  fromLabel = Swizzle \v -> withVec2 v \x y -> vec4 y y y x
+
+instance IsLabel "yyyy" (Swizzle Vec4 Vec2) where
+  fromLabel = Swizzle \v -> withVec2 v \_ y -> vec4 y y y y
+
+-- * From Vec3
+
+-- * To Float
+
+instance IsLabel "x" (Swizzle Float Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x _ _ -> x
+
+instance IsLabel "y" (Swizzle Float Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \_ y _ -> y
+
+instance IsLabel "z" (Swizzle Float Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \_ _ z -> z
+
+-- * To Vec2
+
+instance IsLabel "xx" (Swizzle Vec2 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x _ _ -> vec2 x x
+
+instance IsLabel "xy" (Swizzle Vec2 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x y _ -> vec2 x y
+
+instance IsLabel "xz" (Swizzle Vec2 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x _ z -> vec2 x z
+
+instance IsLabel "yx" (Swizzle Vec2 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x y _ -> vec2 y x
+
+instance IsLabel "yy" (Swizzle Vec2 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \_ y _ -> vec2 y y
+
+instance IsLabel "yz" (Swizzle Vec2 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \_ y z -> vec2 y z
+
+instance IsLabel "zx" (Swizzle Vec2 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x _ z -> vec2 z x
+
+instance IsLabel "zy" (Swizzle Vec2 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \_ y z -> vec2 z y
+
+instance IsLabel "zz" (Swizzle Vec2 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \_ _ z -> vec2 z z
+
+-- * To Vec3
+
+instance IsLabel "xxx" (Swizzle Vec3 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x _ _ -> vec3 x x x
+
+instance IsLabel "xxy" (Swizzle Vec3 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x y _ -> vec3 x x y
+
+instance IsLabel "xxz" (Swizzle Vec3 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x _ z -> vec3 x x z
+
+instance IsLabel "xyx" (Swizzle Vec3 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x y _ -> vec3 x y x
+
+instance IsLabel "xyy" (Swizzle Vec3 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x y _ -> vec3 x y y
+
+instance IsLabel "xzx" (Swizzle Vec3 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x _ z -> vec3 x z x
+
+instance IsLabel "xzy" (Swizzle Vec3 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x y z -> vec3 x z y
+
+instance IsLabel "xzz" (Swizzle Vec3 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x _ z -> vec3 x z z
+
+instance IsLabel "yxx" (Swizzle Vec3 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x y _ -> vec3 y x x
+
+instance IsLabel "yxy" (Swizzle Vec3 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x y _ -> vec3 y x y
+
+instance IsLabel "yxz" (Swizzle Vec3 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x y z -> vec3 y x z
+
+instance IsLabel "yyx" (Swizzle Vec3 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x y _ -> vec3 y y x
+
+instance IsLabel "yyy" (Swizzle Vec3 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \_ y _ -> vec3 y y y
+
+instance IsLabel "yyz" (Swizzle Vec3 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \_ y z -> vec3 y y z
+
+instance IsLabel "yzx" (Swizzle Vec3 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x y z -> vec3 y z x
+
+instance IsLabel "yzy" (Swizzle Vec3 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \_ y z -> vec3 y z y
+
+instance IsLabel "yzz" (Swizzle Vec3 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \_ y z -> vec3 y z z
+
+instance IsLabel "zxx" (Swizzle Vec3 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x _ z -> vec3 z x x
+
+instance IsLabel "zxy" (Swizzle Vec3 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x y z -> vec3 z x y
+
+instance IsLabel "zxz" (Swizzle Vec3 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x _ z -> vec3 z x z
+
+instance IsLabel "zyx" (Swizzle Vec3 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x y z -> vec3 z y x
+
+instance IsLabel "zyy" (Swizzle Vec3 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \_ y z -> vec3 z y y
+
+instance IsLabel "zyz" (Swizzle Vec3 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \_ y z -> vec3 z y z
+
+instance IsLabel "zzx" (Swizzle Vec3 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x _ z -> vec3 z z x
+
+instance IsLabel "zzy" (Swizzle Vec3 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \_ y z -> vec3 z z y
+
+instance IsLabel "zzz" (Swizzle Vec3 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \_ _ z -> vec3 z z z
+
+-- * To Vec4
+
+instance IsLabel "xxxx" (Swizzle Vec4 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x _ _ -> vec4 x x x x
+
+instance IsLabel "xxxy" (Swizzle Vec4 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x y _ -> vec4 x x x y
+
+instance IsLabel "xxxz" (Swizzle Vec4 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x _ z -> vec4 x x x z
+
+instance IsLabel "xxyx" (Swizzle Vec4 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x y _ -> vec4 x x y x
+
+instance IsLabel "xxyy" (Swizzle Vec4 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x y _ -> vec4 x x y y
+
+instance IsLabel "xxyz" (Swizzle Vec4 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x y z -> vec4 x x y z
+
+instance IsLabel "xxzx" (Swizzle Vec4 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x _ z -> vec4 x x z x
+
+instance IsLabel "xxzy" (Swizzle Vec4 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x y z -> vec4 x x z y
+
+instance IsLabel "xxzz" (Swizzle Vec4 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x _ z -> vec4 x x z z
+
+instance IsLabel "xyxx" (Swizzle Vec4 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x y _ -> vec4 x y x x
+
+instance IsLabel "xyxy" (Swizzle Vec4 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x y _ -> vec4 x y x y
+
+instance IsLabel "xyxz" (Swizzle Vec4 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x y z -> vec4 x y x z
+
+instance IsLabel "xyyx" (Swizzle Vec4 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x y _ -> vec4 x y y x
+
+instance IsLabel "xyyy" (Swizzle Vec4 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x y _ -> vec4 x y y y
+
+instance IsLabel "xyyz" (Swizzle Vec4 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x y z -> vec4 x y y z
+
+instance IsLabel "xyzx" (Swizzle Vec4 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x y z -> vec4 x y z x
+
+instance IsLabel "xyzy" (Swizzle Vec4 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x y z -> vec4 x y z y
+
+instance IsLabel "xyzz" (Swizzle Vec4 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x y z -> vec4 x y z z
+
+instance IsLabel "xzxx" (Swizzle Vec4 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x _ z -> vec4 x z x x
+
+instance IsLabel "xzxy" (Swizzle Vec4 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x y z -> vec4 x z x y
+
+instance IsLabel "xzxz" (Swizzle Vec4 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x _ z -> vec4 x z x z
+
+instance IsLabel "xzyx" (Swizzle Vec4 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x y z -> vec4 x z y x
+
+instance IsLabel "xzyy" (Swizzle Vec4 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x y z -> vec4 x z y y
+
+instance IsLabel "xzyz" (Swizzle Vec4 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x y z -> vec4 x z y z
+
+instance IsLabel "xzzx" (Swizzle Vec4 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x _ z -> vec4 x z z x
+
+instance IsLabel "xzzy" (Swizzle Vec4 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x y z -> vec4 x z z y
+
+instance IsLabel "xzzz" (Swizzle Vec4 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x _ z -> vec4 x z z z
+
+instance IsLabel "yxxx" (Swizzle Vec4 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x y _ -> vec4 y x x x
+
+instance IsLabel "yxxy" (Swizzle Vec4 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x y _ -> vec4 y x x y
+
+instance IsLabel "yxxz" (Swizzle Vec4 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x y z -> vec4 y x x z
+
+instance IsLabel "yxyx" (Swizzle Vec4 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x y _ -> vec4 y x y x
+
+instance IsLabel "yxyy" (Swizzle Vec4 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x y _ -> vec4 y x y y
+
+instance IsLabel "yxyz" (Swizzle Vec4 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x y z -> vec4 y x y z
+
+instance IsLabel "yxzx" (Swizzle Vec4 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x y z -> vec4 y x z x
+
+instance IsLabel "yxzy" (Swizzle Vec4 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x y z -> vec4 y x z y
+
+instance IsLabel "yxzz" (Swizzle Vec4 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x y z -> vec4 y x z z
+
+instance IsLabel "yyxx" (Swizzle Vec4 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x y _ -> vec4 y y x x
+
+instance IsLabel "yyxy" (Swizzle Vec4 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x y _ -> vec4 y y x y
+
+instance IsLabel "yyxz" (Swizzle Vec4 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x y z -> vec4 y y x z
+
+instance IsLabel "yyyx" (Swizzle Vec4 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x y _ -> vec4 y y y x
+
+instance IsLabel "yyyy" (Swizzle Vec4 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \_ y _ -> vec4 y y y y
+
+instance IsLabel "yyyz" (Swizzle Vec4 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \_ y z -> vec4 y y y z
+
+instance IsLabel "yyzx" (Swizzle Vec4 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x y z -> vec4 y y z x
+
+instance IsLabel "yyzy" (Swizzle Vec4 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \_ y z -> vec4 y y z y
+
+instance IsLabel "yyzz" (Swizzle Vec4 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \_ y z -> vec4 y y z z
+
+instance IsLabel "yzxx" (Swizzle Vec4 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x y z -> vec4 y z x x
+
+instance IsLabel "yzxy" (Swizzle Vec4 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x y z -> vec4 y z x y
+
+instance IsLabel "yzxz" (Swizzle Vec4 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x y z -> vec4 y z x z
+
+instance IsLabel "yzyx" (Swizzle Vec4 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x y z -> vec4 y z y x
+
+instance IsLabel "yzyy" (Swizzle Vec4 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \_ y z -> vec4 y z y y
+
+instance IsLabel "yzyz" (Swizzle Vec4 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \_ y z -> vec4 y z y z
+
+instance IsLabel "yzzx" (Swizzle Vec4 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x y z -> vec4 y z z x
+
+instance IsLabel "yzzy" (Swizzle Vec4 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \_ y z -> vec4 y z z y
+
+instance IsLabel "yzzz" (Swizzle Vec4 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \_ y z -> vec4 y z z z
+
+instance IsLabel "zxxx" (Swizzle Vec4 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x _ z -> vec4 z x x x
+
+instance IsLabel "zxxy" (Swizzle Vec4 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x y z -> vec4 z x x y
+
+instance IsLabel "zxxz" (Swizzle Vec4 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x _ z -> vec4 z x x z
+
+instance IsLabel "zxyx" (Swizzle Vec4 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x y z -> vec4 z x y x
+
+instance IsLabel "zxyy" (Swizzle Vec4 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x y z -> vec4 z x y y
+
+instance IsLabel "zxyz" (Swizzle Vec4 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x y z -> vec4 z x y z
+
+instance IsLabel "zxzx" (Swizzle Vec4 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x _ z -> vec4 z x z x
+
+instance IsLabel "zxzy" (Swizzle Vec4 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x y z -> vec4 z x z y
+
+instance IsLabel "zxzz" (Swizzle Vec4 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x _ z -> vec4 z x z z
+
+instance IsLabel "zyxx" (Swizzle Vec4 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x y z -> vec4 z y x x
+
+instance IsLabel "zyxy" (Swizzle Vec4 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x y z -> vec4 z y x y
+
+instance IsLabel "zyxz" (Swizzle Vec4 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x y z -> vec4 z y x z
+
+instance IsLabel "zyyx" (Swizzle Vec4 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x y z -> vec4 z y y x
+
+instance IsLabel "zyyy" (Swizzle Vec4 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \_ y z -> vec4 z y y y
+
+instance IsLabel "zyyz" (Swizzle Vec4 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \_ y z -> vec4 z y y z
+
+instance IsLabel "zyzx" (Swizzle Vec4 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x y z -> vec4 z y z x
+
+instance IsLabel "zyzy" (Swizzle Vec4 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \_ y z -> vec4 z y z y
+
+instance IsLabel "zyzz" (Swizzle Vec4 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \_ y z -> vec4 z y z z
+
+instance IsLabel "zzxx" (Swizzle Vec4 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x _ z -> vec4 z z x x
+
+instance IsLabel "zzxy" (Swizzle Vec4 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x y z -> vec4 z z x y
+
+instance IsLabel "zzxz" (Swizzle Vec4 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x _ z -> vec4 z z x z
+
+instance IsLabel "zzyx" (Swizzle Vec4 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x y z -> vec4 z z y x
+
+instance IsLabel "zzyy" (Swizzle Vec4 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \_ y z -> vec4 z z y y
+
+instance IsLabel "zzyz" (Swizzle Vec4 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \_ y z -> vec4 z z y z
+
+instance IsLabel "zzzx" (Swizzle Vec4 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \x _ z -> vec4 z z z x
+
+instance IsLabel "zzzy" (Swizzle Vec4 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \_ y z -> vec4 z z z y
+
+instance IsLabel "zzzz" (Swizzle Vec4 Vec3) where
+  fromLabel = Swizzle \v -> withVec3 v \_ _ z -> vec4 z z z z
+
+-- * From Vec4
+
+-- ** To Float
+
+instance IsLabel "x" (Swizzle Float Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ _ _ -> x
+
+instance IsLabel "y" (Swizzle Float Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y _ _ -> y
+
+instance IsLabel "z" (Swizzle Float Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ _ z _ -> z
+
+instance IsLabel "w" (Swizzle Float Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ _ _ w -> w
+
+-- ** To Vec2
+
+instance IsLabel "xx" (Swizzle Vec2 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ _ _ -> vec2 x x
+
+instance IsLabel "xy" (Swizzle Vec2 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y _ _ -> vec2 x y
+
+instance IsLabel "xz" (Swizzle Vec2 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ z _ -> vec2 x z
+
+instance IsLabel "xw" (Swizzle Vec2 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ _ w -> vec2 x w
+
+instance IsLabel "yx" (Swizzle Vec2 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y _ _ -> vec2 y x
+
+instance IsLabel "yy" (Swizzle Vec2 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y _ _ -> vec2 y y
+
+instance IsLabel "yz" (Swizzle Vec2 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y z _ -> vec2 y z
+
+instance IsLabel "yw" (Swizzle Vec2 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y _ w -> vec2 y w
+
+instance IsLabel "zx" (Swizzle Vec2 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ z _ -> vec2 z x
+
+instance IsLabel "zy" (Swizzle Vec2 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y z _ -> vec2 z y
+
+instance IsLabel "zz" (Swizzle Vec2 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ _ z _ -> vec2 z z
+
+instance IsLabel "zw" (Swizzle Vec2 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ _ z w -> vec2 z w
+
+instance IsLabel "wx" (Swizzle Vec2 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ _ w -> vec2 w x
+
+instance IsLabel "wy" (Swizzle Vec2 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y _ w -> vec2 w y
+
+instance IsLabel "wz" (Swizzle Vec2 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ _ z w -> vec2 w z
+
+instance IsLabel "ww" (Swizzle Vec2 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ _ _ w -> vec2 w w
+
+-- ** To Vec3
+
+instance IsLabel "xxx" (Swizzle Vec3 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ _ _ -> vec3 x x x
+
+instance IsLabel "xxy" (Swizzle Vec3 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y _ _ -> vec3 x x y
+
+instance IsLabel "xxz" (Swizzle Vec3 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ z _ -> vec3 x x z
+
+instance IsLabel "xxw" (Swizzle Vec3 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ _ w -> vec3 x x w
+
+instance IsLabel "xyx" (Swizzle Vec3 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y _ _ -> vec3 x y x
+
+instance IsLabel "xyy" (Swizzle Vec3 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y _ _ -> vec3 x y y
+
+instance IsLabel "xyz" (Swizzle Vec3 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y z _ -> vec3 x y z
+
+instance IsLabel "xyw" (Swizzle Vec3 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y _ w -> vec3 x y w
+
+instance IsLabel "xzx" (Swizzle Vec3 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ z _ -> vec3 x z x
+
+instance IsLabel "xzy" (Swizzle Vec3 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y z _ -> vec3 x z y
+
+instance IsLabel "xzz" (Swizzle Vec3 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ z _ -> vec3 x z z
+
+instance IsLabel "xzw" (Swizzle Vec3 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ z w -> vec3 x z w
+
+instance IsLabel "xwx" (Swizzle Vec3 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ _ w -> vec3 x w x
+
+instance IsLabel "xwy" (Swizzle Vec3 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y _ w -> vec3 x w y
+
+instance IsLabel "xwz" (Swizzle Vec3 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ z w -> vec3 x w z
+
+instance IsLabel "xww" (Swizzle Vec3 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ _ w -> vec3 x w w
+
+instance IsLabel "yxx" (Swizzle Vec3 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y _ _ -> vec3 y x x
+
+instance IsLabel "yxy" (Swizzle Vec3 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y _ _ -> vec3 y x y
+
+instance IsLabel "yxz" (Swizzle Vec3 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y z _ -> vec3 y x z
+
+instance IsLabel "yxw" (Swizzle Vec3 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y _ w -> vec3 y x w
+
+instance IsLabel "yyx" (Swizzle Vec3 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y _ _ -> vec3 y y x
+
+instance IsLabel "yyy" (Swizzle Vec3 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y _ _ -> vec3 y y y
+
+instance IsLabel "yyz" (Swizzle Vec3 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y z _ -> vec3 y y z
+
+instance IsLabel "yyw" (Swizzle Vec3 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y _ w -> vec3 y y w
+
+instance IsLabel "yzx" (Swizzle Vec3 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y z _ -> vec3 y z x
+
+instance IsLabel "yzy" (Swizzle Vec3 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y z _ -> vec3 y z y
+
+instance IsLabel "yzz" (Swizzle Vec3 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y z _ -> vec3 y z z
+
+instance IsLabel "yzw" (Swizzle Vec3 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y z w -> vec3 y z w
+
+instance IsLabel "ywx" (Swizzle Vec3 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y _ w -> vec3 y w x
+
+instance IsLabel "ywy" (Swizzle Vec3 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y _ w -> vec3 y w y
+
+instance IsLabel "ywz" (Swizzle Vec3 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y z w -> vec3 y w z
+
+instance IsLabel "yww" (Swizzle Vec3 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y _ w -> vec3 y w w
+
+instance IsLabel "zxx" (Swizzle Vec3 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ z _ -> vec3 z x x
+
+instance IsLabel "zxy" (Swizzle Vec3 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y z _ -> vec3 z x y
+
+instance IsLabel "zxz" (Swizzle Vec3 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ z _ -> vec3 z x z
+
+instance IsLabel "zxw" (Swizzle Vec3 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ z w -> vec3 z x w
+
+instance IsLabel "zyx" (Swizzle Vec3 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y z _ -> vec3 z y x
+
+instance IsLabel "zyy" (Swizzle Vec3 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y z _ -> vec3 z y y
+
+instance IsLabel "zyz" (Swizzle Vec3 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y z _ -> vec3 z y z
+
+instance IsLabel "zyw" (Swizzle Vec3 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y z w -> vec3 z y w
+
+instance IsLabel "zzx" (Swizzle Vec3 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ z _ -> vec3 z z x
+
+instance IsLabel "zzy" (Swizzle Vec3 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y z _ -> vec3 z z y
+
+instance IsLabel "zzz" (Swizzle Vec3 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ _ z _ -> vec3 z z z
+
+instance IsLabel "zzw" (Swizzle Vec3 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ _ z w -> vec3 z z w
+
+instance IsLabel "zwx" (Swizzle Vec3 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ z w -> vec3 z w x
+
+instance IsLabel "zwy" (Swizzle Vec3 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y z w -> vec3 z w y
+
+instance IsLabel "zwz" (Swizzle Vec3 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ _ z w -> vec3 z w z
+
+instance IsLabel "zww" (Swizzle Vec3 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ _ z w -> vec3 z w w
+
+instance IsLabel "wxx" (Swizzle Vec3 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ _ w -> vec3 w x x
+
+instance IsLabel "wxy" (Swizzle Vec3 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y _ w -> vec3 w x y
+
+instance IsLabel "wxz" (Swizzle Vec3 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ z w -> vec3 w x z
+
+instance IsLabel "wxw" (Swizzle Vec3 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ _ w -> vec3 w x w
+
+instance IsLabel "wyx" (Swizzle Vec3 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y _ w -> vec3 w y x
+
+instance IsLabel "wyy" (Swizzle Vec3 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y _ w -> vec3 w y y
+
+instance IsLabel "wyz" (Swizzle Vec3 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y z w -> vec3 w y z
+
+instance IsLabel "wyw" (Swizzle Vec3 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y _ w -> vec3 w y w
+
+instance IsLabel "wzx" (Swizzle Vec3 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ z w -> vec3 w z x
+
+instance IsLabel "wzy" (Swizzle Vec3 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y z w -> vec3 w z y
+
+instance IsLabel "wzz" (Swizzle Vec3 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ _ z w -> vec3 w z z
+
+instance IsLabel "wzw" (Swizzle Vec3 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ _ z w -> vec3 w z w
+
+instance IsLabel "wwx" (Swizzle Vec3 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ _ w -> vec3 w w x
+
+instance IsLabel "wwy" (Swizzle Vec3 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y _ w -> vec3 w w y
+
+instance IsLabel "wwz" (Swizzle Vec3 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ _ z w -> vec3 w w z
+
+instance IsLabel "www" (Swizzle Vec3 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ _ _ w -> vec3 w w w
+
+-- ** To Vec4
+
+instance IsLabel "xxxx" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ _ _ -> vec4 x x x x
+
+instance IsLabel "xxxy" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y _ _ -> vec4 x x x y
+
+instance IsLabel "xxxz" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ z _ -> vec4 x x x z
+
+instance IsLabel "xxxw" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ _ w -> vec4 x x x w
+
+instance IsLabel "xxyx" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y _ _ -> vec4 x x y x
+
+instance IsLabel "xxyy" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y _ _ -> vec4 x x y y
+
+instance IsLabel "xxyz" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y z _ -> vec4 x x y z
+
+instance IsLabel "xxyw" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y _ w -> vec4 x x y w
+
+instance IsLabel "xxzx" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ z _ -> vec4 x x z x
+
+instance IsLabel "xxzy" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y z _ -> vec4 x x z y
+
+instance IsLabel "xxzz" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ z _ -> vec4 x x z z
+
+instance IsLabel "xxzw" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ z w -> vec4 x x z w
+
+instance IsLabel "xxwx" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ _ w -> vec4 x x w x
+
+instance IsLabel "xxwy" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y _ w -> vec4 x x w y
+
+instance IsLabel "xxwz" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ z w -> vec4 x x w z
+
+instance IsLabel "xxww" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ _ w -> vec4 x x w w
+
+instance IsLabel "xyxx" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y _ _ -> vec4 x y x x
+
+instance IsLabel "xyxy" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y _ _ -> vec4 x y x y
+
+instance IsLabel "xyxz" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y z _ -> vec4 x y x z
+
+instance IsLabel "xyxw" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y _ w -> vec4 x y x w
+
+instance IsLabel "xyyx" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y _ _ -> vec4 x y y x
+
+instance IsLabel "xyyy" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y _ _ -> vec4 x y y y
+
+instance IsLabel "xyyz" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y z _ -> vec4 x y y z
+
+instance IsLabel "xyyw" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y _ w -> vec4 x y y w
+
+instance IsLabel "xyzx" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y z _ -> vec4 x y z x
+
+instance IsLabel "xyzy" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y z _ -> vec4 x y z y
+
+instance IsLabel "xyzz" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y z _ -> vec4 x y z z
+
+instance IsLabel "xywx" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y _ w -> vec4 x y w x
+
+instance IsLabel "xywy" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y _ w -> vec4 x y w y
+
+instance IsLabel "xywz" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y z w -> vec4 x y w z
+
+instance IsLabel "xyww" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y _ w -> vec4 x y w w
+
+instance IsLabel "xzxx" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ z _ -> vec4 x z x x
+
+instance IsLabel "xzxy" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y z _ -> vec4 x z x y
+
+instance IsLabel "xzxz" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ z _ -> vec4 x z x z
+
+instance IsLabel "xzxw" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ z w -> vec4 x z x w
+
+instance IsLabel "xzyx" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y z _ -> vec4 x z y x
+
+instance IsLabel "xzyy" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y z _ -> vec4 x z y y
+
+instance IsLabel "xzyz" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y z _ -> vec4 x z y z
+
+instance IsLabel "xzyw" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y z w -> vec4 x z y w
+
+instance IsLabel "xzzx" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ z _ -> vec4 x z z x
+
+instance IsLabel "xzzy" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y z _ -> vec4 x z z y
+
+instance IsLabel "xzzz" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ z _ -> vec4 x z z z
+
+instance IsLabel "xzzw" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ z w -> vec4 x z z w
+
+instance IsLabel "xzwx" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ z w -> vec4 x z w x
+
+instance IsLabel "xzwy" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y z w -> vec4 x z w y
+
+instance IsLabel "xzwz" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ z w -> vec4 x z w z
+
+instance IsLabel "xzww" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ z w -> vec4 x z w w
+
+instance IsLabel "xwxx" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ _ w -> vec4 x w x x
+
+instance IsLabel "xwxy" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y _ w -> vec4 x w x y
+
+instance IsLabel "xwxz" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ z w -> vec4 x w x z
+
+instance IsLabel "xwxw" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ _ w -> vec4 x w x w
+
+instance IsLabel "xwyx" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y _ w -> vec4 x w y x
+
+instance IsLabel "xwyy" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y _ w -> vec4 x w y y
+
+instance IsLabel "xwyz" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y z w -> vec4 x w y z
+
+instance IsLabel "xwyw" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y _ w -> vec4 x w y w
+
+instance IsLabel "xwzx" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ z w -> vec4 x w z x
+
+instance IsLabel "xwzy" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y z w -> vec4 x w z y
+
+instance IsLabel "xwzz" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ z w -> vec4 x w z z
+
+instance IsLabel "xwzw" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ z w -> vec4 x w z w
+
+instance IsLabel "xwwx" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ _ w -> vec4 x w w x
+
+instance IsLabel "xwwy" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y _ w -> vec4 x w w y
+
+instance IsLabel "xwwz" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ z w -> vec4 x w w z
+
+instance IsLabel "xwww" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ _ w -> vec4 x w w w
+
+instance IsLabel "yxxx" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y _ _ -> vec4 y x x x
+
+instance IsLabel "yxxy" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y _ _ -> vec4 y x x y
+
+instance IsLabel "yxxz" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y z _ -> vec4 y x x z
+
+instance IsLabel "yxxw" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y _ w -> vec4 y x x w
+
+instance IsLabel "yxyx" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y _ _ -> vec4 y x y x
+
+instance IsLabel "yxyy" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y _ _ -> vec4 y x y y
+
+instance IsLabel "yxyz" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y z _ -> vec4 y x y z
+
+instance IsLabel "yxyw" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y _ w -> vec4 y x y w
+
+instance IsLabel "yxzx" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y z _ -> vec4 y x z x
+
+instance IsLabel "yxzy" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y z _ -> vec4 y x z y
+
+instance IsLabel "yxzz" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y z _ -> vec4 y x z z
+
+instance IsLabel "yxzw" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y z w -> vec4 y x z w
+
+instance IsLabel "yxwx" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y _ w -> vec4 y x w x
+
+instance IsLabel "yxwy" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y _ w -> vec4 y x w y
+
+instance IsLabel "yxwz" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y z w -> vec4 y x w z
+
+instance IsLabel "yxww" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y _ w -> vec4 y x w w
+
+instance IsLabel "yyxx" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y _ _ -> vec4 y y x x
+
+instance IsLabel "yyxy" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y _ _ -> vec4 y y x y
+
+instance IsLabel "yyxz" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y z _ -> vec4 y y x z
+
+instance IsLabel "yyxw" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y _ w -> vec4 y y x w
+
+instance IsLabel "yyyx" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y _ _ -> vec4 y y y x
+
+instance IsLabel "yyyy" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y _ _ -> vec4 y y y y
+
+instance IsLabel "yyyz" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y z _ -> vec4 y y y z
+
+instance IsLabel "yyyw" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y _ w -> vec4 y y y w
+
+instance IsLabel "yyzx" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y z _ -> vec4 y y z x
+
+instance IsLabel "yyzy" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y z _ -> vec4 y y z y
+
+instance IsLabel "yyzz" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y z _ -> vec4 y y z z
+
+instance IsLabel "yyzw" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y z w -> vec4 y y z w
+
+instance IsLabel "yywx" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y _ w -> vec4 y y w x
+
+instance IsLabel "yywy" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y _ w -> vec4 y y w y
+
+instance IsLabel "yywz" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y z w -> vec4 y y w z
+
+instance IsLabel "yyww" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y _ w -> vec4 y y w w
+
+instance IsLabel "yzxx" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y z _ -> vec4 y z x x
+
+instance IsLabel "yzxy" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y z _ -> vec4 y z x y
+
+instance IsLabel "yzxz" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y z _ -> vec4 y z x z
+
+instance IsLabel "yzxw" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y z w -> vec4 y z x w
+
+instance IsLabel "yzyx" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y z _ -> vec4 y z y x
+
+instance IsLabel "yzyy" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y z _ -> vec4 y z y y
+
+instance IsLabel "yzyz" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y z _ -> vec4 y z y z
+
+instance IsLabel "yzyw" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y z w -> vec4 y z y w
+
+instance IsLabel "yzzx" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y z _ -> vec4 y z z x
+
+instance IsLabel "yzzy" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y z _ -> vec4 y z z y
+
+instance IsLabel "yzzz" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y z _ -> vec4 y z z z
+
+instance IsLabel "yzzw" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y z w -> vec4 y z z w
+
+instance IsLabel "yzwx" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y z w -> vec4 y z w x
+
+instance IsLabel "yzwy" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y z w -> vec4 y z w y
+
+instance IsLabel "yzwz" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y z w -> vec4 y z w z
+
+instance IsLabel "yzww" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y z w -> vec4 y z w w
+
+instance IsLabel "ywxx" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y _ w -> vec4 y w x x
+
+instance IsLabel "ywxy" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y _ w -> vec4 y w x y
+
+instance IsLabel "ywxz" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y z w -> vec4 y w x z
+
+instance IsLabel "ywxw" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y _ w -> vec4 y w x w
+
+instance IsLabel "ywyx" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y _ w -> vec4 y w y x
+
+instance IsLabel "ywyy" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y _ w -> vec4 y w y y
+
+instance IsLabel "ywyz" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y z w -> vec4 y w y z
+
+instance IsLabel "ywyw" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y _ w -> vec4 y w y w
+
+instance IsLabel "ywzx" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y z w -> vec4 y w z x
+
+instance IsLabel "ywzy" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y z w -> vec4 y w z y
+
+instance IsLabel "ywzz" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y z w -> vec4 y w z z
+
+instance IsLabel "ywzw" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y z w -> vec4 y w z w
+
+instance IsLabel "ywwx" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y _ w -> vec4 y w w x
+
+instance IsLabel "ywwy" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y _ w -> vec4 y w w y
+
+instance IsLabel "ywwz" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y z w -> vec4 y w w z
+
+instance IsLabel "ywww" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y _ w -> vec4 y w w w
+
+instance IsLabel "zxxx" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ z _ -> vec4 z x x x
+
+instance IsLabel "zxxy" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y z _ -> vec4 z x x y
+
+instance IsLabel "zxxz" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ z _ -> vec4 z x x z
+
+instance IsLabel "zxxw" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ z w -> vec4 z x x w
+
+instance IsLabel "zxyx" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y z _ -> vec4 z x y x
+
+instance IsLabel "zxyy" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y z _ -> vec4 z x y y
+
+instance IsLabel "zxyz" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y z _ -> vec4 z x y z
+
+instance IsLabel "zxyw" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y z w -> vec4 z x y w
+
+instance IsLabel "zxzx" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ z _ -> vec4 z x z x
+
+instance IsLabel "zxzy" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y z _ -> vec4 z x z y
+
+instance IsLabel "zxzz" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ z _ -> vec4 z x z z
+
+instance IsLabel "zxzw" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ z w -> vec4 z x z w
+
+instance IsLabel "zxwx" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ z w -> vec4 z x w x
+
+instance IsLabel "zxwy" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y z w -> vec4 z x w y
+
+instance IsLabel "zxwz" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ z w -> vec4 z x w z
+
+instance IsLabel "zxww" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ z w -> vec4 z x w w
+
+instance IsLabel "zyxx" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y z _ -> vec4 z y x x
+
+instance IsLabel "zyxy" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y z _ -> vec4 z y x y
+
+instance IsLabel "zyxz" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y z _ -> vec4 z y x z
+
+instance IsLabel "zyxw" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y z w -> vec4 z y x w
+
+instance IsLabel "zyyx" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y z _ -> vec4 z y y x
+
+instance IsLabel "zyyy" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y z _ -> vec4 z y y y
+
+instance IsLabel "zyyz" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y z _ -> vec4 z y y z
+
+instance IsLabel "zyyw" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y z w -> vec4 z y y w
+
+instance IsLabel "zyzx" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y z _ -> vec4 z y z x
+
+instance IsLabel "zyzy" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y z _ -> vec4 z y z y
+
+instance IsLabel "zyzz" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y z _ -> vec4 z y z z
+
+instance IsLabel "zyzw" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y z w -> vec4 z y z w
+
+instance IsLabel "zywx" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y z w -> vec4 z y w x
+
+instance IsLabel "zywy" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y z w -> vec4 z y w y
+
+instance IsLabel "zywz" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y z w -> vec4 z y w z
+
+instance IsLabel "zyww" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y z w -> vec4 z y w w
+
+instance IsLabel "zzxx" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ z _ -> vec4 z z x x
+
+instance IsLabel "zzxy" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y z _ -> vec4 z z x y
+
+instance IsLabel "zzxz" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ z _ -> vec4 z z x z
+
+instance IsLabel "zzxw" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ z w -> vec4 z z x w
+
+instance IsLabel "zzyx" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y z _ -> vec4 z z y x
+
+instance IsLabel "zzyy" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y z _ -> vec4 z z y y
+
+instance IsLabel "zzyz" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y z _ -> vec4 z z y z
+
+instance IsLabel "zzyw" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y z w -> vec4 z z y w
+
+instance IsLabel "zzzx" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ z _ -> vec4 z z z x
+
+instance IsLabel "zzzy" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y z _ -> vec4 z z z y
+
+instance IsLabel "zzzz" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ _ z _ -> vec4 z z z z
+
+instance IsLabel "zzzw" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ _ z w -> vec4 z z z w
+
+instance IsLabel "zzwx" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ z w -> vec4 z z w x
+
+instance IsLabel "zzwy" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y z w -> vec4 z z w y
+
+instance IsLabel "zzwz" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ _ z w -> vec4 z z w z
+
+instance IsLabel "zzww" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ _ z w -> vec4 z z w w
+
+instance IsLabel "zwxx" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ z w -> vec4 z w x x
+
+instance IsLabel "zwxy" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y z w -> vec4 z w x y
+
+instance IsLabel "zwxz" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ z w -> vec4 z w x z
+
+instance IsLabel "zwxw" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ z w -> vec4 z w x w
+
+instance IsLabel "zwyx" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y z w -> vec4 z w y x
+
+instance IsLabel "zwyy" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y z w -> vec4 z w y y
+
+instance IsLabel "zwyz" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y z w -> vec4 z w y z
+
+instance IsLabel "zwyw" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y z w -> vec4 z w y w
+
+instance IsLabel "zwzx" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ z w -> vec4 z w z x
+
+instance IsLabel "zwzy" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y z w -> vec4 z w z y
+
+instance IsLabel "zwzz" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ _ z w -> vec4 z w z z
+
+instance IsLabel "zwzw" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ _ z w -> vec4 z w z w
+
+instance IsLabel "zwwx" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ z w -> vec4 z w w x
+
+instance IsLabel "zwwy" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y z w -> vec4 z w w y
+
+instance IsLabel "zwwz" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ _ z w -> vec4 z w w z
+
+instance IsLabel "zwww" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ _ z w -> vec4 z w w w
+
+instance IsLabel "wxxx" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ _ w -> vec4 w x x x
+
+instance IsLabel "wxxy" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y _ w -> vec4 w x x y
+
+instance IsLabel "wxxz" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ z w -> vec4 w x x z
+
+instance IsLabel "wxxw" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ _ w -> vec4 w x x w
+
+instance IsLabel "wxyx" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y _ w -> vec4 w x y x
+
+instance IsLabel "wxyy" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y _ w -> vec4 w x y y
+
+instance IsLabel "wxyz" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y z w -> vec4 w x y z
+
+instance IsLabel "wxyw" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y _ w -> vec4 w x y w
+
+instance IsLabel "wxzx" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ z w -> vec4 w x z x
+
+instance IsLabel "wxzy" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y z w -> vec4 w x z y
+
+instance IsLabel "wxzz" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ z w -> vec4 w x z z
+
+instance IsLabel "wxzw" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ z w -> vec4 w x z w
+
+instance IsLabel "wxwx" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ _ w -> vec4 w x w x
+
+instance IsLabel "wxwy" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y _ w -> vec4 w x w y
+
+instance IsLabel "wxwz" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ z w -> vec4 w x w z
+
+instance IsLabel "wxww" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ _ w -> vec4 w x w w
+
+instance IsLabel "wyxx" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y _ w -> vec4 w y x x
+
+instance IsLabel "wyxy" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y _ w -> vec4 w y x y
+
+instance IsLabel "wyxz" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y z w -> vec4 w y x z
+
+instance IsLabel "wyxw" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y _ w -> vec4 w y x w
+
+instance IsLabel "wyyx" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y _ w -> vec4 w y y x
+
+instance IsLabel "wyyy" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y _ w -> vec4 w y y y
+
+instance IsLabel "wyyz" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y z w -> vec4 w y y z
+
+instance IsLabel "wyyw" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y _ w -> vec4 w y y w
+
+instance IsLabel "wyzx" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y z w -> vec4 w y z x
+
+instance IsLabel "wyzy" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y z w -> vec4 w y z y
+
+instance IsLabel "wyzz" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y z w -> vec4 w y z z
+
+instance IsLabel "wyzw" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y z w -> vec4 w y z w
+
+instance IsLabel "wywx" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y _ w -> vec4 w y w x
+
+instance IsLabel "wywy" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y _ w -> vec4 w y w y
+
+instance IsLabel "wywz" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y z w -> vec4 w y w z
+
+instance IsLabel "wyww" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y _ w -> vec4 w y w w
+
+instance IsLabel "wzxx" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ z w -> vec4 w z x x
+
+instance IsLabel "wzxy" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y z w -> vec4 w z x y
+
+instance IsLabel "wzxz" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ z w -> vec4 w z x z
+
+instance IsLabel "wzxw" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ z w -> vec4 w z x w
+
+instance IsLabel "wzyx" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y z w -> vec4 w z y x
+
+instance IsLabel "wzyy" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y z w -> vec4 w z y y
+
+instance IsLabel "wzyz" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y z w -> vec4 w z y z
+
+instance IsLabel "wzyw" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y z w -> vec4 w z y w
+
+instance IsLabel "wzzx" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ z w -> vec4 w z z x
+
+instance IsLabel "wzzy" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y z w -> vec4 w z z y
+
+instance IsLabel "wzzz" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ _ z w -> vec4 w z z z
+
+instance IsLabel "wzzw" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ _ z w -> vec4 w z z w
+
+instance IsLabel "wzwx" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ z w -> vec4 w z w x
+
+instance IsLabel "wzwy" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y z w -> vec4 w z w y
+
+instance IsLabel "wzwz" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ _ z w -> vec4 w z w z
+
+instance IsLabel "wzww" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ _ z w -> vec4 w z w w
+
+instance IsLabel "wwxx" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ _ w -> vec4 w w x x
+
+instance IsLabel "wwxy" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y _ w -> vec4 w w x y
+
+instance IsLabel "wwxz" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ z w -> vec4 w w x z
+
+instance IsLabel "wwxw" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ _ w -> vec4 w w x w
+
+instance IsLabel "wwyx" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x y _ w -> vec4 w w y x
+
+instance IsLabel "wwyy" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y _ w -> vec4 w w y y
+
+instance IsLabel "wwyz" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y z w -> vec4 w w y z
+
+instance IsLabel "wwyw" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y _ w -> vec4 w w y w
+
+instance IsLabel "wwzx" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ z w -> vec4 w w z x
+
+instance IsLabel "wwzy" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y z w -> vec4 w w z y
+
+instance IsLabel "wwzz" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ _ z w -> vec4 w w z z
+
+instance IsLabel "wwzw" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ _ z w -> vec4 w w z w
+
+instance IsLabel "wwwx" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \x _ _ w -> vec4 w w w x
+
+instance IsLabel "wwwy" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ y _ w -> vec4 w w w y
+
+instance IsLabel "wwwz" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ _ z w -> vec4 w w w z
+
+instance IsLabel "wwww" (Swizzle Vec4 Vec4) where
+  fromLabel = Swizzle \v -> withVec4 v \_ _ _ w -> vec4 w w w w
diff --git a/src/Geomancy/UVec2.hs b/src/Geomancy/UVec2.hs
--- a/src/Geomancy/UVec2.hs
+++ b/src/Geomancy/UVec2.hs
@@ -1,5 +1,6 @@
 {-# LANGUAGE BlockArguments #-}
 {-# LANGUAGE PatternSynonyms #-}
+{-# LANGUAGE TypeFamilies #-}
 {-# LANGUAGE ViewPatterns #-}
 
 -- | Specialized and inlined @V2 Word32@.
@@ -14,8 +15,11 @@
 
 import Control.DeepSeq (NFData(rnf))
 import Data.Word (Word32)
+import Data.MonoTraversable (Element, MonoFunctor(..), MonoPointed(..))
 import Foreign (Storable(..))
 
+import Geomancy.Elementwise (Elementwise(..))
+
 data UVec2 = UVec2
   {-# UNPACK #-} !Word32
   {-# UNPACK #-} !Word32
@@ -42,6 +46,57 @@
 
 instance NFData UVec2 where
   rnf UVec2{} = ()
+
+type instance Element UVec2 = Word32
+
+instance MonoFunctor UVec2 where
+  {-# INLINE omap #-}
+  omap f v =
+    withUVec2 v \x y ->
+      uvec2 (f x) (f y)
+
+instance MonoPointed UVec2 where
+  {-# INLINE opoint #-}
+  opoint x = uvec2 x x
+
+instance Elementwise UVec2 where
+  {-# INLINE emap2 #-}
+  emap2 f p0 p1 =
+    withUVec2 p0 \x0 y0 ->
+    withUVec2 p1 \x1 y1 ->
+      uvec2
+        (f x0 x1)
+        (f y0 y1)
+
+  {-# INLINE emap3 #-}
+  emap3 f p0 p1 p2 =
+    withUVec2 p0 \x0 y0 ->
+    withUVec2 p1 \x1 y1 ->
+    withUVec2 p2 \x2 y2 ->
+      uvec2
+        (f x0 x1 x2)
+        (f y0 y1 y2)
+
+  {-# INLINE emap4 #-}
+  emap4 f p0 p1 p2 p3 =
+    withUVec2 p0 \x0 y0 ->
+    withUVec2 p1 \x1 y1 ->
+    withUVec2 p2 \x2 y2 ->
+    withUVec2 p3 \x3 y3 ->
+      uvec2
+        (f x0 x1 x2 x3)
+        (f y0 y1 y2 y3)
+
+  {-# INLINE emap5 #-}
+  emap5 f p0 p1 p2 p3 p4 =
+    withUVec2 p0 \x0 y0 ->
+    withUVec2 p1 \x1 y1 ->
+    withUVec2 p2 \x2 y2 ->
+    withUVec2 p3 \x3 y3 ->
+    withUVec2 p4 \x4 y4 ->
+      uvec2
+        (f x0 x1 x2 x3 x4)
+        (f y0 y1 y2 y3 y4)
 
 -- XXX: That's one nasty instance...
 instance Num UVec2 where
diff --git a/src/Geomancy/UVec3.hs b/src/Geomancy/UVec3.hs
--- a/src/Geomancy/UVec3.hs
+++ b/src/Geomancy/UVec3.hs
@@ -1,6 +1,7 @@
 {-# LANGUAGE BlockArguments #-}
 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
 {-# LANGUAGE PatternSynonyms #-}
+{-# LANGUAGE TypeFamilies #-}
 {-# LANGUAGE ViewPatterns #-}
 
 -- | Specialized and inlined @V2 Word32@.
@@ -18,8 +19,11 @@
 
 import Control.DeepSeq (NFData(rnf))
 import Data.Word (Word32)
+import Data.MonoTraversable (Element, MonoFunctor(..), MonoPointed(..))
 import Foreign (Storable(..))
 
+import Geomancy.Elementwise (Elementwise(..))
+
 data UVec3 = UVec3
   {-# UNPACK #-} !Word32
   {-# UNPACK #-} !Word32
@@ -47,6 +51,61 @@
 
 instance NFData UVec3 where
   rnf UVec3{} = ()
+
+type instance Element UVec3 = Word32
+
+instance MonoFunctor UVec3 where
+  {-# INLINE omap #-}
+  omap f v =
+    withUVec3 v \x y z ->
+      uvec3 (f x) (f y) (f z)
+
+instance MonoPointed UVec3 where
+  {-# INLINE opoint #-}
+  opoint x = uvec3 x x x
+
+instance Elementwise UVec3 where
+  {-# INLINE emap2 #-}
+  emap2 f p0 p1 =
+    withUVec3 p0 \x0 y0 z0 ->
+    withUVec3 p1 \x1 y1 z1 ->
+      uvec3
+        (f x0 x1)
+        (f y0 y1)
+        (f z0 z1)
+
+  {-# INLINE emap3 #-}
+  emap3 f p0 p1 p2 =
+    withUVec3 p0 \x0 y0 z0 ->
+    withUVec3 p1 \x1 y1 z1 ->
+    withUVec3 p2 \x2 y2 z2 ->
+      uvec3
+        (f x0 x1 x2)
+        (f y0 y1 y2)
+        (f z0 z1 z2)
+
+  {-# INLINE emap4 #-}
+  emap4 f p0 p1 p2 p3 =
+    withUVec3 p0 \x0 y0 z0 ->
+    withUVec3 p1 \x1 y1 z1 ->
+    withUVec3 p2 \x2 y2 z2 ->
+    withUVec3 p3 \x3 y3 z3 ->
+      uvec3
+        (f x0 x1 x2 x3)
+        (f y0 y1 y2 y3)
+        (f z0 z1 z2 z3)
+
+  {-# INLINE emap5 #-}
+  emap5 f p0 p1 p2 p3 p4 =
+    withUVec3 p0 \x0 y0 z0 ->
+    withUVec3 p1 \x1 y1 z1 ->
+    withUVec3 p2 \x2 y2 z2 ->
+    withUVec3 p3 \x3 y3 z3 ->
+    withUVec3 p4 \x4 y4 z4 ->
+      uvec3
+        (f x0 x1 x2 x3 x4)
+        (f y0 y1 y2 y3 y4)
+        (f z0 z1 z2 z3 z4)
 
 -- XXX: That's another nasty instance...
 instance Num UVec3 where
diff --git a/src/Geomancy/UVec4.hs b/src/Geomancy/UVec4.hs
--- a/src/Geomancy/UVec4.hs
+++ b/src/Geomancy/UVec4.hs
@@ -1,5 +1,6 @@
 {-# LANGUAGE BlockArguments #-}
 {-# LANGUAGE PatternSynonyms #-}
+{-# LANGUAGE TypeFamilies #-}
 {-# LANGUAGE ViewPatterns #-}
 
 -- | Specialized and inlined @V2 Word32@.
@@ -14,8 +15,11 @@
 
 import Control.DeepSeq (NFData(rnf))
 import Data.Word (Word32)
+import Data.MonoTraversable (Element, MonoFunctor(..), MonoPointed(..))
 import Foreign (Storable(..))
 
+import Geomancy.Elementwise (Elementwise(..))
+
 data UVec4 = UVec4
   {-# UNPACK #-} !Word32
   {-# UNPACK #-} !Word32
@@ -44,6 +48,65 @@
 
 instance NFData UVec4 where
   rnf UVec4{} = ()
+
+type instance Element UVec4 = Word32
+
+instance MonoFunctor UVec4 where
+  {-# INLINE omap #-}
+  omap f v =
+    withUVec4 v \x y z w ->
+      uvec4 (f x) (f y) (f z) (f w)
+
+instance MonoPointed UVec4 where
+  {-# INLINE opoint #-}
+  opoint x = uvec4 x x x x
+
+instance Elementwise UVec4 where
+  {-# INLINE emap2 #-}
+  emap2 f p0 p1 =
+    withUVec4 p0 \x0 y0 z0 w0 ->
+    withUVec4 p1 \x1 y1 z1 w1 ->
+      uvec4
+        (f x0 x1)
+        (f y0 y1)
+        (f z0 z1)
+        (f w0 w1)
+
+  {-# INLINE emap3 #-}
+  emap3 f p0 p1 p2 =
+    withUVec4 p0 \x0 y0 z0 w0 ->
+    withUVec4 p1 \x1 y1 z1 w1 ->
+    withUVec4 p2 \x2 y2 z2 w2 ->
+      uvec4
+        (f x0 x1 x2)
+        (f y0 y1 y2)
+        (f z0 z1 z2)
+        (f w0 w1 w2)
+
+  {-# INLINE emap4 #-}
+  emap4 f p0 p1 p2 p3 =
+    withUVec4 p0 \x0 y0 z0 w0 ->
+    withUVec4 p1 \x1 y1 z1 w1 ->
+    withUVec4 p2 \x2 y2 z2 w2 ->
+    withUVec4 p3 \x3 y3 z3 w3 ->
+      uvec4
+        (f x0 x1 x2 x3)
+        (f y0 y1 y2 y3)
+        (f z0 z1 z2 z3)
+        (f w0 w1 w2 w3)
+
+  {-# INLINE emap5 #-}
+  emap5 f p0 p1 p2 p3 p4 =
+    withUVec4 p0 \x0 y0 z0 w0 ->
+    withUVec4 p1 \x1 y1 z1 w1 ->
+    withUVec4 p2 \x2 y2 z2 w2 ->
+    withUVec4 p3 \x3 y3 z3 w3 ->
+    withUVec4 p4 \x4 y4 z4 w4 ->
+      uvec4
+        (f x0 x1 x2 x3 x4)
+        (f y0 y1 y2 y3 y4)
+        (f z0 z1 z2 z3 z4)
+        (f w0 w1 w2 w3 w4)
 
 -- XXX: That's another nasty instance...
 instance Num UVec4 where
diff --git a/src/Geomancy/Vec2.hs b/src/Geomancy/Vec2.hs
--- a/src/Geomancy/Vec2.hs
+++ b/src/Geomancy/Vec2.hs
@@ -1,5 +1,7 @@
 {-# LANGUAGE BlockArguments #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
 {-# LANGUAGE PatternSynonyms #-}
+{-# LANGUAGE TypeFamilies #-}
 {-# LANGUAGE ViewPatterns #-}
 
 -- | Specialized and inlined @V2 Float@.
@@ -20,8 +22,14 @@
   ) where
 
 import Control.DeepSeq (NFData(rnf))
+import Data.MonoTraversable (Element, MonoFunctor(..), MonoPointed(..))
+import Data.VectorSpace (VectorSpace)
 import Foreign (Storable(..))
+import qualified Data.VectorSpace as VectorSpace
 
+import Geomancy.Elementwise (Elementwise(..))
+import Geomancy.Gl.Funs (GlModf(..), GlNearest)
+
 data Vec2 = Vec2
   {-# UNPACK #-} !Float
   {-# UNPACK #-} !Float
@@ -49,6 +57,56 @@
 instance NFData Vec2 where
   rnf Vec2{} = ()
 
+type instance Element Vec2 = Float
+
+instance MonoFunctor Vec2 where
+  {-# INLINE omap #-}
+  omap f v =
+    withVec2 v \x y ->
+      vec2 (f x) (f y)
+
+instance MonoPointed Vec2 where
+  opoint x = vec2 x x
+
+instance Elementwise Vec2 where
+  {-# INLINE emap2 #-}
+  emap2 f p0 p1 =
+    withVec2 p0 \x0 y0 ->
+    withVec2 p1 \x1 y1 ->
+      vec2
+        (f x0 x1)
+        (f y0 y1)
+
+  {-# INLINE emap3 #-}
+  emap3 f p0 p1 p2 =
+    withVec2 p0 \x0 y0 ->
+    withVec2 p1 \x1 y1 ->
+    withVec2 p2 \x2 y2 ->
+      vec2
+        (f x0 x1 x2)
+        (f y0 y1 y2)
+
+  {-# INLINE emap4 #-}
+  emap4 f p0 p1 p2 p3 =
+    withVec2 p0 \x0 y0 ->
+    withVec2 p1 \x1 y1 ->
+    withVec2 p2 \x2 y2 ->
+    withVec2 p3 \x3 y3 ->
+      vec2
+        (f x0 x1 x2 x3)
+        (f y0 y1 y2 y3)
+
+  {-# INLINE emap5 #-}
+  emap5 f p0 p1 p2 p3 p4 =
+    withVec2 p0 \x0 y0 ->
+    withVec2 p1 \x1 y1 ->
+    withVec2 p2 \x2 y2 ->
+    withVec2 p3 \x3 y3 ->
+    withVec2 p4 \x4 y4 ->
+      vec2
+        (f x0 x1 x2 x3 x4)
+        (f y0 y1 y2 y3 y4)
+
 instance Num Vec2 where
   {-# INLINE (+) #-}
   Vec2 l1 l2 + Vec2 r1 r2 =
@@ -95,6 +153,25 @@
     where
       x' = fromRational x
 
+instance Floating Vec2 where
+  pi = opoint pi
+
+  exp = omap exp
+  log = omap log
+  sqrt = omap sqrt
+  sin = omap sin
+  cos = omap cos
+  asin = omap asin
+  acos = omap acos
+  atan = omap atan
+  sinh = omap sinh
+  cosh = omap cosh
+  asinh = omap asinh
+  acosh = omap acosh
+  atanh = omap atanh
+
+  (**) = emap2 (**)
+
 {-# INLINE (^*) #-}
 (^*) :: Vec2 -> Float -> Vec2
 Vec2 a b ^* x =
@@ -152,3 +229,40 @@
   peek ptr = vec2
     <$> peekByteOff ptr 0
     <*> peekByteOff ptr 4
+
+instance VectorSpace Vec2 Float where
+  zeroVector = epoint 0
+
+  {-# INLINE (*^) #-}
+  a *^ v = v Geomancy.Vec2.^* a
+
+  {-# INLINE (^/) #-}
+  v ^/ a = v Geomancy.Vec2.^/ a
+
+  {-# INLINE (^+^) #-}
+  (^+^) = emap2 (+)
+
+  {-# INLINE (^-^) #-}
+  (^-^) = emap2 (-)
+
+  {-# INLINE negateVector #-}
+  negateVector = emap negate
+
+  {-# INLINE dot #-}
+  dot = Geomancy.Vec2.dot
+
+  {-# INLINE normalize #-}
+  normalize = Geomancy.Vec2.normalize
+
+instance GlNearest Vec2
+
+instance GlModf Vec2 Vec2 where
+  glModf v =
+    withVec2 v \vx vy ->
+      let
+        (xi, xf) = glModf vx
+        (yi, yf) = glModf vy
+      in
+        ( vec2 (fromInteger xi) (fromInteger yi)
+        , vec2 xf yf
+        )
diff --git a/src/Geomancy/Vec3.hs b/src/Geomancy/Vec3.hs
--- a/src/Geomancy/Vec3.hs
+++ b/src/Geomancy/Vec3.hs
@@ -1,8 +1,12 @@
 {-# LANGUAGE BlockArguments #-}
 {-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE FlexibleInstances #-}
 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
 {-# LANGUAGE PatternSynonyms #-}
+{-# LANGUAGE TypeFamilies #-}
 {-# LANGUAGE ViewPatterns #-}
+{-# LANGUAGE DerivingStrategies #-}
 
 -- | Specialized and inlined @V3 Float@.
 
@@ -24,12 +28,21 @@
 
   , Packed(..)
   , packed
+
+  , emap2
+  , emap3
+  , emap4
   ) where
 
 import Control.DeepSeq (NFData(rnf))
 import Data.Coerce (Coercible, coerce)
+import Data.MonoTraversable (Element, MonoFunctor(..), MonoPointed(..))
+import Data.VectorSpace (VectorSpace)
 import Foreign (Storable(..), castPtr)
+import qualified Data.VectorSpace as VectorSpace
 
+import Geomancy.Elementwise (Elementwise(..))
+import Geomancy.Gl.Funs (GlModf(..), GlNearest)
 import Geomancy.Vec2 (Vec2, withVec2)
 
 data Vec3 = Vec3
@@ -66,6 +79,60 @@
 instance NFData Vec3 where
   rnf Vec3{} = ()
 
+type instance Element Vec3 = Float
+
+instance MonoFunctor Vec3 where
+  {-# INLINE omap #-}
+  omap f v =
+    withVec3 v \x y z ->
+      vec3 (f x) (f y) (f z)
+
+instance MonoPointed Vec3 where
+  opoint x = vec3 x x x
+
+instance Elementwise Vec3 where
+  {-# INLINE emap2 #-}
+  emap2 f p0 p1 =
+    withVec3 p0 \x0 y0 z0 ->
+    withVec3 p1 \x1 y1 z1 ->
+      vec3
+        (f x0 x1)
+        (f y0 y1)
+        (f z0 z1)
+
+  {-# INLINE emap3 #-}
+  emap3 f p0 p1 p2 =
+    withVec3 p0 \x0 y0 z0 ->
+    withVec3 p1 \x1 y1 z1 ->
+    withVec3 p2 \x2 y2 z2 ->
+      vec3
+        (f x0 x1 x2)
+        (f y0 y1 y2)
+        (f z0 z1 z2)
+
+  {-# INLINE emap4 #-}
+  emap4 f p0 p1 p2 p3 =
+    withVec3 p0 \x0 y0 z0 ->
+    withVec3 p1 \x1 y1 z1 ->
+    withVec3 p2 \x2 y2 z2 ->
+    withVec3 p3 \x3 y3 z3 ->
+      vec3
+        (f x0 x1 x2 x3)
+        (f y0 y1 y2 y3)
+        (f z0 z1 z2 z3)
+
+  {-# INLINE emap5 #-}
+  emap5 f p0 p1 p2 p3 p4 =
+    withVec3 p0 \x0 y0 z0 ->
+    withVec3 p1 \x1 y1 z1 ->
+    withVec3 p2 \x2 y2 z2 ->
+    withVec3 p3 \x3 y3 z3 ->
+    withVec3 p4 \x4 y4 z4 ->
+      vec3
+        (f x0 x1 x2 x3 x4)
+        (f y0 y1 y2 y3 y4)
+        (f z0 z1 z2 z3 z4)
+
 instance Num Vec3 where
   {-# INLINE (+) #-}
   Vec3 a b c + Vec3 d e f =
@@ -115,6 +182,31 @@
     where
       x' = fromRational x
 
+instance Floating Vec3 where
+  pi = opoint pi
+
+  exp = omap exp
+  log = omap log
+  sqrt = omap sqrt
+  sin = omap sin
+  cos = omap cos
+  asin = omap asin
+  acos = omap acos
+  atan = omap atan
+  sinh = omap sinh
+  cosh = omap cosh
+  asinh = omap asinh
+  acosh = omap acosh
+  atanh = omap atanh
+
+  a ** b =
+    withVec3 a \ax ay az ->
+    withVec3 b \bx by bz ->
+      vec3
+        (ax ** bx)
+        (ay ** by)
+        (az ** bz)
+
 {-
   XXX: GPU layouts call for some padding.
 
@@ -195,10 +287,43 @@
 
     nearZero a = abs a <= 1e-6
 
+instance VectorSpace Vec3 Float where
+  zeroVector = epoint 0
+
+  {-# INLINE (*^) #-}
+  (*^) = flip (Geomancy.Vec3.^*)
+
+  {-# INLINE (^/) #-}
+  (^/) = (Geomancy.Vec3.^/)
+
+  {-# INLINE (^+^) #-}
+  (^+^) = emap2 (+)
+
+  {-# INLINE (^-^) #-}
+  (^-^) = emap2 (-)
+
+  {-# INLINE negateVector #-}
+  negateVector = emap negate
+
+  {-# INLINE dot #-}
+  dot = Geomancy.Vec3.dot
+
+  {-# INLINE normalize #-}
+  normalize = Geomancy.Vec3.normalize
+
 -- * Unpadded
 
+type instance Element Packed = Float
+
 newtype Packed = Packed { unPacked :: Vec3 }
-  deriving (Eq, Ord, Show, NFData, Num, Fractional)
+  deriving stock
+    ( Eq, Ord, Show
+    )
+  deriving newtype
+    ( NFData, Num, Fractional, Floating
+    , MonoFunctor, MonoPointed
+    , Elementwise
+    )
 
 {-# INLINE packed #-}
 packed :: Float -> Float -> Float -> Packed
@@ -227,3 +352,41 @@
     <*> peekElemOff ptr' 2
     where
       ptr' = castPtr ptr
+
+instance VectorSpace Packed Float where
+  zeroVector = epoint 0
+
+  {-# INLINE (*^) #-}
+  (*^) = flip $ coerce (Geomancy.Vec3.^*)
+
+  {-# INLINE (^/) #-}
+  (^/) = coerce (Geomancy.Vec3.^/)
+
+  {-# INLINE (^+^) #-}
+  v1 ^+^ v2 = v1 + v2
+
+  {-# INLINE (^-^) #-}
+  v1 ^-^ v2 = v1 - v2
+
+  {-# INLINE negateVector #-}
+  negateVector = emap negate
+
+  {-# INLINE dot #-}
+  dot = coerce Geomancy.Vec3.dot
+
+  {-# INLINE normalize #-}
+  normalize = coerce Geomancy.Vec3.normalize
+
+instance GlNearest Vec3
+
+instance GlModf Vec3 Vec3 where
+  glModf v =
+    withVec3 v \vx vy vz ->
+      let
+        (xi, xf) = glModf vx
+        (yi, yf) = glModf vy
+        (zi, zf) = glModf vz
+      in
+        ( vec3 (fromInteger xi) (fromInteger yi) (fromInteger zi)
+        , vec3 xf yf zf
+        )
diff --git a/src/Geomancy/Vec4.hs b/src/Geomancy/Vec4.hs
--- a/src/Geomancy/Vec4.hs
+++ b/src/Geomancy/Vec4.hs
@@ -2,7 +2,9 @@
 {-# LANGUAGE BlockArguments #-}
 {-# LANGUAGE FlexibleContexts #-}
 {-# LANGUAGE MagicHash #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
 {-# LANGUAGE PatternSynonyms #-}
+{-# LANGUAGE TypeFamilies #-}
 {-# LANGUAGE UnboxedTuples #-}
 {-# LANGUAGE UnliftedFFITypes #-}
 {-# LANGUAGE ViewPatterns #-}
@@ -32,11 +34,15 @@
 import GHC.Exts hiding (VecCount(..), toList)
 
 import Control.DeepSeq (NFData(rnf))
+import Data.MonoTraversable (Element, MonoFunctor(..), MonoPointed(..))
+import Data.VectorSpace (VectorSpace)
 import Foreign (Storable(..))
 import GHC.IO (IO(..))
--- import System.IO.Unsafe (unsafePerformIO)
 import Text.Printf (printf)
+import qualified Data.VectorSpace as VectorSpace
 
+import Geomancy.Elementwise (Elementwise(..))
+import Geomancy.Gl.Funs (GlModf(..), GlNearest)
 import Geomancy.Vec2 (Vec2, withVec2)
 import Geomancy.Vec3 (Vec3, withVec3)
 
@@ -123,6 +129,64 @@
 instance NFData Vec4 where
   rnf Vec4{} = ()
 
+type instance Element Vec4 = Float
+
+instance MonoFunctor Vec4 where
+  {-# INLINE omap #-}
+  omap f v =
+    withVec4 v \x y z w ->
+      vec4 (f x) (f y) (f z) (f w)
+
+instance MonoPointed Vec4 where
+  opoint x = vec4 x x x x
+
+instance Elementwise Vec4 where
+  {-# INLINE emap2 #-}
+  emap2 f p0 p1 =
+    withVec4 p0 \x0 y0 z0 w0 ->
+    withVec4 p1 \x1 y1 z1 w1 ->
+      vec4
+        (f x0 x1)
+        (f y0 y1)
+        (f z0 z1)
+        (f w0 w1)
+
+  {-# INLINE emap3 #-}
+  emap3 f p0 p1 p2 =
+    withVec4 p0 \x0 y0 z0 w0 ->
+    withVec4 p1 \x1 y1 z1 w1 ->
+    withVec4 p2 \x2 y2 z2 w2 ->
+      vec4
+        (f x0 x1 x2)
+        (f y0 y1 y2)
+        (f z0 z1 z2)
+        (f w0 w1 w2)
+
+  {-# INLINE emap4 #-}
+  emap4 f p0 p1 p2 p3 =
+    withVec4 p0 \x0 y0 z0 w0 ->
+    withVec4 p1 \x1 y1 z1 w1 ->
+    withVec4 p2 \x2 y2 z2 w2 ->
+    withVec4 p3 \x3 y3 z3 w3 ->
+      vec4
+        (f x0 x1 x2 x3)
+        (f y0 y1 y2 y3)
+        (f z0 z1 z2 z3)
+        (f w0 w1 w2 w3)
+
+  {-# INLINE emap5 #-}
+  emap5 f p0 p1 p2 p3 p4 =
+    withVec4 p0 \x0 y0 z0 w0 ->
+    withVec4 p1 \x1 y1 z1 w1 ->
+    withVec4 p2 \x2 y2 z2 w2 ->
+    withVec4 p3 \x3 y3 z3 w3 ->
+    withVec4 p4 \x4 y4 z4 w4 ->
+      vec4
+        (f x0 x1 x2 x3 x4)
+        (f y0 y1 y2 y3 y4)
+        (f z0 z1 z2 z3 z4)
+        (f w0 w1 w2 w3 w4)
+
 instance Num Vec4 where
   {-# INLINE (+) #-}
   (+) l r =
@@ -186,6 +250,32 @@
     where
       x' = fromRational x
 
+instance Floating Vec4 where
+  pi = opoint pi
+
+  exp = omap exp
+  log = omap log
+  sqrt = omap sqrt
+  sin = omap sin
+  cos = omap cos
+  asin = omap asin
+  acos = omap acos
+  atan = omap atan
+  sinh = omap sinh
+  cosh = omap cosh
+  asinh = omap asinh
+  acosh = omap acosh
+  atanh = omap atanh
+
+  a ** b =
+    withVec4 a \ax ay az aw ->
+    withVec4 b \bx by bz bw ->
+      vec4
+        (ax ** bx)
+        (ay ** by)
+        (az ** bz)
+        (aw ** bw)
+
 instance Storable Vec4 where
   {-# INLINE sizeOf #-}
   sizeOf _ = 16
@@ -209,6 +299,30 @@
     in
       (# world', Vec4 arr' #)
 
+instance VectorSpace Vec4 Float where
+  zeroVector = epoint 0
+
+  {-# INLINE (*^) #-}
+  (*^) = flip (Geomancy.Vec4.^*)
+
+  {-# INLINE (^/) #-}
+  (^/) = (Geomancy.Vec4.^/)
+
+  {-# INLINE (^+^) #-}
+  (^+^) = emap2 (+)
+
+  {-# INLINE (^-^) #-}
+  (^-^) = emap2 (-)
+
+  {-# INLINE negateVector #-}
+  negateVector = emap negate
+
+  {-# INLINE dot #-}
+  dot = Geomancy.Vec4.dot
+
+  {-# INLINE normalize #-}
+  normalize = Geomancy.Vec4.normalize
+
 -- TODO: SIMD
 {-# INLINE (^*) #-}
 (^*) :: Vec4 -> Float -> Vec4
@@ -262,3 +376,18 @@
       !(# _world', arr #) = unsafeFreezeByteArray# arr_ world_
     in
       (# world, Vec4 arr #)
+
+instance GlNearest Vec4
+
+instance GlModf Vec4 Vec4 where
+  glModf v =
+    withVec4 v \vx vy vz vw ->
+      let
+        (xi, xf) = glModf vx
+        (yi, yf) = glModf vy
+        (zi, zf) = glModf vz
+        (wi, wf) = glModf vw
+      in
+        ( vec4 (fromInteger xi) (fromInteger yi) (fromInteger zi) (fromInteger wi)
+        , vec4 xf yf zf wf
+        )
diff --git a/src/Geomancy/Vector.hs b/src/Geomancy/Vector.hs
new file mode 100644
--- /dev/null
+++ b/src/Geomancy/Vector.hs
@@ -0,0 +1,31 @@
+{-# LANGUAGE FlexibleContexts #-}
+
+module Geomancy.Vector
+  ( VectorSpace(..)
+  , (^*)
+  , quadrance
+  , lerp
+  , lerpClip
+  ) where
+
+import Data.VectorSpace (VectorSpace(..))
+import Geomancy.Interpolate (linear)
+
+{-# INLINE (^*) #-}
+(^*) :: VectorSpace v a => v -> a -> v
+(^*) = flip (*^)
+
+{-# INLINE quadrance #-}
+quadrance :: VectorSpace v a => v -> a
+quadrance v = dot v v
+
+{-# INLINE lerp #-}
+lerp :: VectorSpace v a => v -> v -> a -> v
+lerp = linear
+
+{-# INLINE lerpClip #-}
+lerpClip :: (VectorSpace v a, Ord a) => v -> v -> a -> v
+lerpClip a b t
+  | t <= 0 = a
+  | t >= 1 = b
+  | otherwise = lerp a b t
