diff --git a/CHANGELOG b/CHANGELOG
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,10 @@
+2023-04-07 Ivan Perez <ivan.perez@keera.co.uk>
+        * Version bump (0.2.1) (#24).
+        * Conform to style guide (#20).
+        * Enable tests only with GHC 8.4 (#21).
+        * Do not install alex or happy in CI job unless tests are enabled (#22).
+        * Update GHC versions in CI job (#23).
+
 2022-10-12 Ivan Perez <ivan.perez@keera.co.uk>
         * Version bump (0.2) (#19).
         * Move type constraints to default methods (#17).
diff --git a/simple-affine-space.cabal b/simple-affine-space.cabal
--- a/simple-affine-space.cabal
+++ b/simple-affine-space.cabal
@@ -1,5 +1,5 @@
 name: simple-affine-space
-version: 0.2
+version: 0.2.1
 cabal-version: >= 1.10
 license: BSD3
 license-file: LICENSE
diff --git a/src/Data/AffineSpace.hs b/src/Data/AffineSpace.hs
--- a/src/Data/AffineSpace.hs
+++ b/src/Data/AffineSpace.hs
@@ -1,5 +1,5 @@
-{-# LANGUAGE FunctionalDependencies, FlexibleInstances #-}
------------------------------------------------------------------------------------------
+{-# LANGUAGE FlexibleInstances      #-}
+{-# LANGUAGE FunctionalDependencies #-}
 -- |
 -- Module      :  Data.AffineSpace
 -- Copyright   :  (c) Antony Courtney and Henrik Nilsson, Yale University, 2003
@@ -10,42 +10,33 @@
 -- Portability :  non-portable (GHC extensions)
 --
 -- Affine space type relation.
---
------------------------------------------------------------------------------------------
-
 module Data.AffineSpace where
 
+-- Internal imports
 import Data.VectorSpace
 
 infix 6 .+^, .-^, .-.
 
--- Maybe origin should not be a class method, even though an origin
--- can be assocoated with any affine space.
--- Maybe distance should not be a class method, in which case the constraint
--- on the coefficient space (a) could be Fractional (i.e., a Field), which
--- seems closer to the mathematical definition of affine space, provided
--- the constraint on the coefficient space for VectorSpace is also Fractional.
-
 -- | Affine Space type relation.
 --
 -- An affine space is a set (type) @p@, and an associated vector space @v@ over
 -- a field @a@.
 class (Floating a, VectorSpace v a) => AffineSpace p v a | p -> v, v -> a where
 
-    -- | Origin of the affine space.
-    origin   :: p
+  -- | Origin of the affine space.
+  origin :: p
 
-    -- | Addition of affine point and vector.
-    (.+^)    :: p -> v -> p
+  -- | Addition of affine point and vector.
+  (.+^) :: p -> v -> p
 
-    -- | Subtraction of affine point and vector.
-    (.-^)    :: p -> v -> p
-    p .-^ v = p .+^ (negateVector v)
+  -- | Subtraction of affine point and vector.
+  (.-^) :: p -> v -> p
+  p .-^ v = p .+^ negateVector v
 
-    -- | Subtraction of two points in the affine space, giving a vector.
-    (.-.)    :: p -> p -> v
+  -- | Subtraction of two points in the affine space, giving a vector.
+  (.-.) :: p -> p -> v
 
-    -- | Distance between two points in the affine space, same as the 'norm' of
-    -- the vector they form (see '(.-.)'.
-    distance :: p -> p -> a
-    distance p1 p2 = norm (p1 .-. p2)
+  -- | Distance between two points in the affine space, same as the 'norm' of
+  -- the vector they form (see '(.-.)'.
+  distance :: p -> p -> a
+  distance p1 p2 = norm (p1 .-. p2)
diff --git a/src/Data/Point2.hs b/src/Data/Point2.hs
--- a/src/Data/Point2.hs
+++ b/src/Data/Point2.hs
@@ -1,6 +1,8 @@
+{-# LANGUAGE ExistentialQuantification #-}
+{-# LANGUAGE FlexibleInstances         #-}
+{-# LANGUAGE MultiParamTypeClasses     #-}
+{-# LANGUAGE StandaloneDeriving        #-}
 {-# OPTIONS_GHC -fno-warn-warnings-deprecations #-}
-{-# LANGUAGE ExistentialQuantification, MultiParamTypeClasses, FlexibleInstances, StandaloneDeriving #-}
------------------------------------------------------------------------------------------
 -- |
 -- Module      :  Data.Point2
 -- Copyright   :  (c) Antony Courtney and Henrik Nilsson, Yale University, 2003
@@ -11,20 +13,20 @@
 -- Portability :  non-portable (GHC extensions)
 --
 -- 2D point abstraction (R^2).
---
------------------------------------------------------------------------------------------
-
-module Data.Point2 (
-    Point2(..), -- Non-abstract, instance of AffineSpace
-    point2X,    -- :: RealFloat a => Point2 a -> a
-    point2Y     -- :: RealFloat a => Point2 a -> a
-) where
+module Data.Point2
+    ( Point2(..) -- Non-abstract, instance of AffineSpace
+    , point2X    -- :: RealFloat a => Point2 a -> a
+    , point2Y    -- :: RealFloat a => Point2 a -> a
+    )
+  where
 
+-- External imports
 import Control.DeepSeq (NFData(..))
 
-import Data.VectorSpace ()
+-- Internal imports
 import Data.AffineSpace
 import Data.Vector2
+import Data.VectorSpace ()
 
 -- * 2D point, constructors and selectors
 
@@ -49,10 +51,10 @@
 -- * Affine space instance
 
 instance RealFloat a => AffineSpace (Point2 a) (Vector2 a) a where
-    origin = Point2 0 0
+  origin = Point2 0 0
 
-    (Point2 x y) .+^ v = Point2 (x + vector2X v) (y + vector2Y v)
+  (Point2 x y) .+^ v = Point2 (x + vector2X v) (y + vector2Y v)
 
-    (Point2 x y) .-^ v = Point2 (x - vector2X v) (y - vector2Y v)
+  (Point2 x y) .-^ v = Point2 (x - vector2X v) (y - vector2Y v)
 
-    (Point2 x1 y1) .-. (Point2 x2 y2) = vector2 (x1 - x2) (y1 - y2)
+  (Point2 x1 y1) .-. (Point2 x2 y2) = vector2 (x1 - x2) (y1 - y2)
diff --git a/src/Data/Point3.hs b/src/Data/Point3.hs
--- a/src/Data/Point3.hs
+++ b/src/Data/Point3.hs
@@ -1,6 +1,8 @@
+{-# LANGUAGE ExistentialQuantification #-}
+{-# LANGUAGE FlexibleInstances         #-}
+{-# LANGUAGE MultiParamTypeClasses     #-}
+{-# LANGUAGE StandaloneDeriving        #-}
 {-# OPTIONS_GHC -fno-warn-warnings-deprecations #-}
-{-# LANGUAGE ExistentialQuantification, MultiParamTypeClasses, FlexibleInstances, StandaloneDeriving #-}
------------------------------------------------------------------------------------------
 -- |
 -- Module      :  Data.Point3
 -- Copyright   :  (c) Antony Courtney and Henrik Nilsson, Yale University, 2003
@@ -11,21 +13,21 @@
 -- Portability :  non-portable (GHC extensions)
 --
 -- 3D point abstraction (R^3).
---
------------------------------------------------------------------------------------------
-
-module Data.Point3 (
-    Point3(..), -- Non-abstract, instance of AffineSpace
-    point3X,    -- :: RealFloat a => Point3 a -> a
-    point3Y,    -- :: RealFloat a => Point3 a -> a
-    point3Z     -- :: RealFloat a => Point3 a -> a
-) where
+module Data.Point3
+    ( Point3(..) -- Non-abstract, instance of AffineSpace
+    , point3X    -- :: RealFloat a => Point3 a -> a
+    , point3Y    -- :: RealFloat a => Point3 a -> a
+    , point3Z    -- :: RealFloat a => Point3 a -> a
+    )
+  where
 
+-- External imports
 import Control.DeepSeq (NFData(..))
 
-import Data.VectorSpace ()
+-- Internal imports
 import Data.AffineSpace
 import Data.Vector3
+import Data.VectorSpace ()
 
 -- * 3D point, constructors and selectors
 
@@ -39,28 +41,28 @@
 instance NFData a => NFData (Point3 a) where
   rnf (Point3 x y z) = rnf x `seq` rnf y `seq` rnf z `seq` ()
 
--- | X coodinate of a 3D point.
+-- | X coordinate of a 3D point.
 point3X :: RealFloat a => Point3 a -> a
 point3X (Point3 x _ _) = x
 
--- | Y coodinate of a 3D point.
+-- | Y coordinate of a 3D point.
 point3Y :: RealFloat a => Point3 a -> a
 point3Y (Point3 _ y _) = y
 
--- | Z coodinate of a 3D point.
+-- | Z coordinate of a 3D point.
 point3Z :: RealFloat a => Point3 a -> a
 point3Z (Point3 _ _ z) = z
 
 -- * Affine space instance
 
 instance RealFloat a => AffineSpace (Point3 a) (Vector3 a) a where
-    origin = Point3 0 0 0
+  origin = Point3 0 0 0
 
-    (Point3 x y z) .+^ v =
-        Point3 (x + vector3X v) (y + vector3Y v) (z + vector3Z v)
+  (Point3 x y z) .+^ v =
+    Point3 (x + vector3X v) (y + vector3Y v) (z + vector3Z v)
 
-    (Point3 x y z) .-^ v =
-        Point3 (x - vector3X v) (y - vector3Y v) (z - vector3Z v)
+  (Point3 x y z) .-^ v =
+    Point3 (x - vector3X v) (y - vector3Y v) (z - vector3Z v)
 
-    (Point3 x1 y1 z1) .-. (Point3 x2 y2 z2) =
-        vector3 (x1 - x2) (y1 - y2) (z1 - z2)
+  (Point3 x1 y1 z1) .-. (Point3 x2 y2 z2) =
+    vector3 (x1 - x2) (y1 - y2) (z1 - z2)
diff --git a/src/Data/Vector2.hs b/src/Data/Vector2.hs
--- a/src/Data/Vector2.hs
+++ b/src/Data/Vector2.hs
@@ -1,6 +1,8 @@
+{-# LANGUAGE ExistentialQuantification #-}
+{-# LANGUAGE FlexibleInstances         #-}
+{-# LANGUAGE MultiParamTypeClasses     #-}
+{-# LANGUAGE StandaloneDeriving        #-}
 {-# OPTIONS_GHC -fno-warn-warnings-deprecations #-}
-{-# LANGUAGE ExistentialQuantification, MultiParamTypeClasses, FlexibleInstances, StandaloneDeriving #-}
------------------------------------------------------------------------------------------
 -- |
 -- Module      :  Data.Vector2
 -- Copyright   :  (c) Antony Courtney and Henrik Nilsson, Yale University, 2003
@@ -11,24 +13,24 @@
 -- Portability :  non-portable (GHC extensions)
 --
 -- 2D vector abstraction (R^2).
---
------------------------------------------------------------------------------------------
-
-module Data.Vector2 (
-    Vector2,            -- Abstract, instance of VectorSpace
-    vector2,            -- :: RealFloat a => a -> a -> Vector2 a
-    vector2X,           -- :: RealFloat a => Vector2 a -> a
-    vector2Y,           -- :: RealFloat a => Vector2 a -> a
-    vector2XY,          -- :: RealFloat a => Vector2 a -> (a, a)
-    vector2Polar,       -- :: RealFloat a => a -> a -> Vector2 a
-    vector2Rho,         -- :: RealFloat a => Vector2 a -> a
-    vector2Theta,       -- :: RealFloat a => Vector2 a -> a
-    vector2RhoTheta,    -- :: RealFloat a => Vector2 a -> (a, a)
-    vector2Rotate       -- :: RealFloat a => a -> Vector2 a -> Vector2 a
-) where
+module Data.Vector2
+    ( Vector2         -- Abstract, instance of VectorSpace
+    , vector2         -- :: RealFloat a => a -> a -> Vector2 a
+    , vector2X        -- :: RealFloat a => Vector2 a -> a
+    , vector2Y        -- :: RealFloat a => Vector2 a -> a
+    , vector2XY       -- :: RealFloat a => Vector2 a -> (a, a)
+    , vector2Polar    -- :: RealFloat a => a -> a -> Vector2 a
+    , vector2Rho      -- :: RealFloat a => Vector2 a -> a
+    , vector2Theta    -- :: RealFloat a => Vector2 a -> a
+    , vector2RhoTheta -- :: RealFloat a => Vector2 a -> (a, a)
+    , vector2Rotate   -- :: RealFloat a => a -> Vector2 a -> Vector2 a
+    )
+  where
 
+-- External imports
 import Control.DeepSeq (NFData(..))
 
+-- Internal imports
 import Data.VectorSpace
 
 -- * 2D vector, constructors and selectors
@@ -84,20 +86,19 @@
 -- * Vector space instance
 
 instance RealFloat a => VectorSpace (Vector2 a) a where
-    zeroVector = Vector2 0 0
-
-    a *^ (Vector2 x y) = Vector2 (a * x) (a * y)
+  zeroVector = Vector2 0 0
 
-    (Vector2 x y) ^/ a = Vector2 (x / a) (y / a)
+  a *^ (Vector2 x y) = Vector2 (a * x) (a * y)
 
-    negateVector (Vector2 x y) = (Vector2 (-x) (-y))
+  (Vector2 x y) ^/ a = Vector2 (x / a) (y / a)
 
-    (Vector2 x1 y1) ^+^ (Vector2 x2 y2) = Vector2 (x1 + x2) (y1 + y2)
+  negateVector (Vector2 x y) = Vector2 (-x) (-y)
 
-    (Vector2 x1 y1) ^-^ (Vector2 x2 y2) = Vector2 (x1 - x2) (y1 - y2)
+  (Vector2 x1 y1) ^+^ (Vector2 x2 y2) = Vector2 (x1 + x2) (y1 + y2)
 
-    (Vector2 x1 y1) `dot` (Vector2 x2 y2) = x1 * x2 + y1 * y2
+  (Vector2 x1 y1) ^-^ (Vector2 x2 y2) = Vector2 (x1 - x2) (y1 - y2)
 
+  (Vector2 x1 y1) `dot` (Vector2 x2 y2) = x1 * x2 + y1 * y2
 
 -- * Additional operations
 
diff --git a/src/Data/Vector3.hs b/src/Data/Vector3.hs
--- a/src/Data/Vector3.hs
+++ b/src/Data/Vector3.hs
@@ -1,6 +1,8 @@
+{-# LANGUAGE ExistentialQuantification #-}
+{-# LANGUAGE FlexibleInstances         #-}
+{-# LANGUAGE MultiParamTypeClasses     #-}
+{-# LANGUAGE StandaloneDeriving        #-}
 {-# OPTIONS_GHC -fno-warn-warnings-deprecations #-}
-{-# LANGUAGE ExistentialQuantification, MultiParamTypeClasses, FlexibleInstances, StandaloneDeriving #-}
------------------------------------------------------------------------------------------
 -- |
 -- Module      :  Data.Vector3
 -- Copyright   :  (c) Antony Courtney and Henrik Nilsson, Yale University, 2003
@@ -11,26 +13,26 @@
 -- Portability :  non-portable (GHC extensions)
 --
 -- 3D vector abstraction (R^3).
---
------------------------------------------------------------------------------------------
-
-module Data.Vector3 (
-    Vector3,            -- Abstract, instance of VectorSpace
-    vector3,            -- :: RealFloat a => a -> a -> a -> Vector3 a
-    vector3X,           -- :: RealFloat a => Vector3 a -> a
-    vector3Y,           -- :: RealFloat a => Vector3 a -> a
-    vector3Z,           -- :: RealFloat a => Vector3 a -> a
-    vector3XYZ,         -- :: RealFloat a => Vector3 a -> (a, a, a)
-    vector3Spherical,   -- :: RealFloat a => a -> a -> a -> Vector3 a
-    vector3Rho,         -- :: RealFloat a => Vector3 a -> a
-    vector3Theta,       -- :: RealFloat a => Vector3 a -> a
-    vector3Phi,         -- :: RealFloat a => Vector3 a -> a
-    vector3RhoThetaPhi, -- :: RealFloat a => Vector3 a -> (a, a, a)
-    vector3Rotate       -- :: RealFloat a => a -> a -> Vector3 a -> Vector3 a
-) where
+module Data.Vector3
+    ( Vector3            -- Abstract, instance of VectorSpace
+    , vector3            -- :: RealFloat a => a -> a -> a -> Vector3 a
+    , vector3X           -- :: RealFloat a => Vector3 a -> a
+    , vector3Y           -- :: RealFloat a => Vector3 a -> a
+    , vector3Z           -- :: RealFloat a => Vector3 a -> a
+    , vector3XYZ         -- :: RealFloat a => Vector3 a -> (a, a, a)
+    , vector3Spherical   -- :: RealFloat a => a -> a -> a -> Vector3 a
+    , vector3Rho         -- :: RealFloat a => Vector3 a -> a
+    , vector3Theta       -- :: RealFloat a => Vector3 a -> a
+    , vector3Phi         -- :: RealFloat a => Vector3 a -> a
+    , vector3RhoThetaPhi -- :: RealFloat a => Vector3 a -> (a, a, a)
+    , vector3Rotate      -- :: RealFloat a => a -> a -> Vector3 a -> Vector3 a
+    )
+  where
 
+-- External imports
 import Control.DeepSeq (NFData(..))
 
+-- Internal imports
 import Data.VectorSpace
 
 -- * 3D vector, constructors and selectors
@@ -75,8 +77,8 @@
 vector3Spherical :: RealFloat a => a -> a -> a -> Vector3 a
 vector3Spherical rho theta phi =
     Vector3 (rhoSinPhi * cos theta) (rhoSinPhi * sin theta) (rho * cos phi)
-    where
-        rhoSinPhi = rho * sin phi
+  where
+    rhoSinPhi = rho * sin phi
 
 -- | Calculates the vector's radial distance.
 vector3Rho :: RealFloat a => Vector3 a -> a
@@ -93,33 +95,35 @@
 -- | Spherical coordinate representation of a 3D vector.
 vector3RhoThetaPhi :: RealFloat a => Vector3 a -> (a, a, a)
 vector3RhoThetaPhi (Vector3 x y z) = (rho, theta, phi)
-    where
-        rho   = sqrt (x * x + y * y + z * z)
-        theta = atan2 y x
-        phi   = acos (z / rho)
+  where
+    rho   = sqrt (x * x + y * y + z * z)
+    theta = atan2 y x
+    phi   = acos (z / rho)
 
 -- * Vector space instance
 
 instance RealFloat a => VectorSpace (Vector3 a) a where
-    zeroVector = Vector3 0 0 0
+  zeroVector = Vector3 0 0 0
 
-    a *^ (Vector3 x y z) = Vector3 (a * x) (a * y) (a * z)
+  a *^ (Vector3 x y z) = Vector3 (a * x) (a * y) (a * z)
 
-    (Vector3 x y z) ^/ a = Vector3 (x / a) (y / a) (z / a)
+  (Vector3 x y z) ^/ a = Vector3 (x / a) (y / a) (z / a)
 
-    negateVector (Vector3 x y z) = (Vector3 (-x) (-y) (-z))
+  negateVector (Vector3 x y z) = Vector3 (-x) (-y) (-z)
 
-    (Vector3 x1 y1 z1) ^+^ (Vector3 x2 y2 z2) = Vector3 (x1+x2) (y1+y2) (z1+z2)
+  (Vector3 x1 y1 z1) ^+^ (Vector3 x2 y2 z2) =
+    Vector3 (x1 + x2) (y1 + y2) (z1 + z2)
 
-    (Vector3 x1 y1 z1) ^-^ (Vector3 x2 y2 z2) = Vector3 (x1-x2) (y1-y2) (z1-z2)
+  (Vector3 x1 y1 z1) ^-^ (Vector3 x2 y2 z2) =
+    Vector3 (x1 - x2) (y1 - y2) (z1 - z2)
 
-    (Vector3 x1 y1 z1) `dot` (Vector3 x2 y2 z2) = x1 * x2 + y1 * y2 + z1 * z2
+  (Vector3 x1 y1 z1) `dot` (Vector3 x2 y2 z2) = x1 * x2 + y1 * y2 + z1 * z2
 
 -- * Additional operations
 
 -- | Rotates a vector with a given polar and azimuthal angles.
 vector3Rotate :: RealFloat a => a -> a -> Vector3 a -> Vector3 a
 vector3Rotate theta' phi' v =
-    vector3Spherical (vector3Rho v)
-                     (vector3Theta v + theta')
-                     (vector3Phi v + phi')
+  vector3Spherical (vector3Rho v)
+                   (vector3Theta v + theta')
+                   (vector3Phi v + phi')
diff --git a/src/Data/VectorSpace.hs b/src/Data/VectorSpace.hs
--- a/src/Data/VectorSpace.hs
+++ b/src/Data/VectorSpace.hs
@@ -1,6 +1,6 @@
-{-# LANGUAGE FunctionalDependencies, FlexibleInstances #-}
-{-# LANGUAGE DefaultSignatures #-}
------------------------------------------------------------------------------------------
+{-# LANGUAGE DefaultSignatures      #-}
+{-# LANGUAGE FlexibleInstances      #-}
+{-# LANGUAGE FunctionalDependencies #-}
 -- |
 -- Module      :  Data.VectorSpace
 -- Copyright   :  (c) Antony Courtney and Henrik Nilsson, Yale University, 2003
@@ -14,14 +14,14 @@
 --
 -- There can be other implementations of VectorSpace, for example you could
 -- implement it with linear like this:
--- 
+--
 -- @
 -- {-# LANGUAGE FlexibleInstances     #-}
 -- {-# LANGUAGE MultiParamTypeClasses #-}
--- 
+--
 -- import FRP.Yampa
 -- import Linear    as L
--- 
+--
 -- instance (Eq a, Floating a) => VectorSpace (V2 a) a where
 --   zeroVector = L.zero
 --   (*^) = (L.*^)
@@ -31,12 +31,10 @@
 --   (^-^) = (L.^-^)
 --   dot = L.dot
 -- @
--- 
+--
 -- Using this you could benefit from more advanced vector operators and the
 -- improved performance linear brings while keeping a simple type class
 -- interface with few dependencies.
------------------------------------------------------------------------------------------
-
 module Data.VectorSpace where
 
 infixr *^
@@ -44,10 +42,6 @@
 infix 7 `dot`
 infixl 6 ^+^, ^-^
 
--- Maybe norm and normalize should not be class methods, in which case
--- the constraint on the coefficient space (a) should (or, at least, could)
--- be Fractional (roughly a Field) rather than Floating.
-
 -- | Vector space type relation.
 --
 --   A vector space is a set (type) closed under addition and multiplication by
@@ -56,152 +50,155 @@
 --
 --   The encoding uses a type class |VectorSpace| @v a@, where @v@ represents
 --   the type of the vectors and @a@ represents the types of the scalars.
-
 class VectorSpace v a | v -> a where
-    -- | Vector with no magnitude (unit for addition).
-    zeroVector :: v
 
-    -- | Multiplication by a scalar.
-    (*^) :: a -> v -> v
+  -- | Vector with no magnitude (unit for addition).
+  zeroVector :: v
 
-    -- | Division by a scalar.
-    (^/) :: v -> a -> v
-    default (^/) :: Fractional a => v -> a -> v
-    v ^/ a = (1/a) *^ v
+  -- | Multiplication by a scalar.
+  (*^) :: a -> v -> v
 
-    -- | Vector addition
-    (^+^) :: v -> v -> v
+  -- | Division by a scalar.
+  (^/) :: v -> a -> v
+  default (^/) :: Fractional a => v -> a -> v
+  v ^/ a = (1 / a) *^ v
 
-    -- | Vector subtraction
-    (^-^) :: v -> v -> v
-    v1 ^-^ v2 = v1 ^+^ negateVector v2
+  -- | Vector addition
+  (^+^) :: v -> v -> v
 
-    -- | Vector negation. Addition with a negated vector should be
-    --   same as subtraction.
-    negateVector :: v -> v
-    default negateVector :: Num a => v -> v
-    negateVector v = (-1) *^ v
+  -- | Vector subtraction
+  (^-^) :: v -> v -> v
+  v1 ^-^ v2 = v1 ^+^ negateVector v2
 
-    -- | Dot product (also known as scalar or inner product).
-    --
-    -- For two vectors, mathematically represented as @a = a1,a2,...,an@ and @b
-    -- = b1,b2,...,bn@, the dot product is @a . b = a1*b1 + a2*b2 + ... +
-    -- an*bn@.
-    --
-    -- Some properties are derived from this. The dot product of a vector with
-    -- itself is the square of its magnitude ('norm'), and the dot product of
-    -- two orthogonal vectors is zero.
-    dot :: v -> v -> a
+  -- | Vector negation. Addition with a negated vector should be
+  --   same as subtraction.
+  negateVector :: v -> v
+  default negateVector :: Num a => v -> v
+  negateVector v = (-1) *^ v
 
-    -- | Vector's norm (also known as magnitude).
-    --
-    -- For a vector represented mathematically as @a = a1,a2,...,an@, the norm
-    -- is the square root of @a1^2 + a2^2 + ... + an^2@.
-    norm :: v -> a
-    default norm :: Floating a => v -> a
-    norm v = sqrt (v `dot` v)
+  -- | Dot product (also known as scalar or inner product).
+  --
+  -- For two vectors, mathematically represented as @a = a1,a2,...,an@ and @b
+  -- = b1,b2,...,bn@, the dot product is @a . b = a1*b1 + a2*b2 + ... +
+  -- an*bn@.
+  --
+  -- Some properties are derived from this. The dot product of a vector with
+  -- itself is the square of its magnitude ('norm'), and the dot product of
+  -- two orthogonal vectors is zero.
+  dot :: v -> v -> a
 
-    -- | Return a vector with the same origin and orientation (angle), but such
-    -- that the norm is one (the unit for multiplication by a scalar).
-    normalize    :: v -> v
-    default normalize :: (Eq a, Floating a) => v -> v
-    normalize v = if nv /= 0 then v ^/ nv else error "normalize: zero vector"
-        where nv = norm v
+  -- | Vector's norm (also known as magnitude).
+  --
+  -- For a vector represented mathematically as @a = a1,a2,...,an@, the norm
+  -- is the square root of @a1^2 + a2^2 + ... + an^2@.
+  norm :: v -> a
+  default norm :: Floating a => v -> a
+  norm v = sqrt (v `dot` v)
 
+  -- | Return a vector with the same origin and orientation (angle), but such
+  -- that the norm is one (the unit for multiplication by a scalar).
+  normalize :: v -> v
+  default normalize :: (Eq a, Floating a) => v -> v
+  normalize v = if nv /= 0 then v ^/ nv else error "normalize: zero vector"
+    where
+      nv = norm v
+
 -- | Vector space instance for 'Float's, with 'Float' scalars.
 instance VectorSpace Float Float where
-    zeroVector = 0
+  zeroVector = 0
 
-    a *^ x = a * x
+  a *^ x = a * x
 
-    x ^/ a = x / a
+  x ^/ a = x / a
 
-    negateVector x = (-x)
+  negateVector x = -x
 
-    x1 ^+^ x2 = x1 + x2
+  x1 ^+^ x2 = x1 + x2
 
-    x1 ^-^ x2 = x1 - x2
+  x1 ^-^ x2 = x1 - x2
 
-    x1 `dot` x2 = x1 * x2
+  x1 `dot` x2 = x1 * x2
 
 -- | Vector space instance for 'Double's, with 'Double' scalars.
 instance VectorSpace Double Double where
-    zeroVector = 0
-
-    a *^ x = a * x
+  zeroVector = 0
 
-    x ^/ a = x / a
+  a *^ x = a * x
 
-    negateVector x = (-x)
+  x ^/ a = x / a
 
-    x1 ^+^ x2 = x1 + x2
+  negateVector x = -x
 
-    x1 ^-^ x2 = x1 - x2
+  x1 ^+^ x2 = x1 + x2
 
-    x1 `dot` x2 = x1 * x2
+  x1 ^-^ x2 = x1 - x2
 
+  x1 `dot` x2 = x1 * x2
 
 -- | Vector space instance for pairs of 'Floating' point numbers.
-instance (Eq a, Floating a) => VectorSpace (a,a) a where
-    zeroVector = (0,0)
+instance (Eq a, Floating a) => VectorSpace (a, a) a where
+  zeroVector = (0, 0)
 
-    a *^ (x,y) = (a * x, a * y)
+  a *^ (x, y) = (a * x, a * y)
 
-    (x,y) ^/ a = (x / a, y / a)
+  (x, y) ^/ a = (x / a, y / a)
 
-    negateVector (x,y) = (-x, -y)
+  negateVector (x, y) = (-x, -y)
 
-    (x1,y1) ^+^ (x2,y2) = (x1 + x2, y1 + y2)
+  (x1, y1) ^+^ (x2, y2) = (x1 + x2, y1 + y2)
 
-    (x1,y1) ^-^ (x2,y2) = (x1 - x2, y1 - y2)
+  (x1, y1) ^-^ (x2, y2) = (x1 - x2, y1 - y2)
 
-    (x1,y1) `dot` (x2,y2) = x1 * x2 + y1 * y2
+  (x1, y1) `dot` (x2, y2) = x1 * x2 + y1 * y2
 
 -- | Vector space instance for triplets of 'Floating' point numbers.
-instance (Eq a, Floating a) => VectorSpace (a,a,a) a where
-    zeroVector = (0,0,0)
+instance (Eq a, Floating a) => VectorSpace (a, a, a) a where
+  zeroVector = (0, 0, 0)
 
-    a *^ (x,y,z) = (a * x, a * y, a * z)
+  a *^ (x, y, z) = (a * x, a * y, a * z)
 
-    (x,y,z) ^/ a = (x / a, y / a, z / a)
+  (x, y, z) ^/ a = (x / a, y / a, z / a)
 
-    negateVector (x,y,z) = (-x, -y, -z)
+  negateVector (x, y, z) = (-x, -y, -z)
 
-    (x1,y1,z1) ^+^ (x2,y2,z2) = (x1+x2, y1+y2, z1+z2)
+  (x1, y1, z1) ^+^ (x2, y2, z2) = (x1 + x2, y1 + y2, z1 + z2)
 
-    (x1,y1,z1) ^-^ (x2,y2,z2) = (x1-x2, y1-y2, z1-z2)
+  (x1, y1, z1) ^-^ (x2, y2, z2) = (x1 - x2, y1 - y2, z1 - z2)
 
-    (x1,y1,z1) `dot` (x2,y2,z2) = x1 * x2 + y1 * y2 + z1 * z2
+  (x1, y1, z1) `dot` (x2, y2, z2) = x1 * x2 + y1 * y2 + z1 * z2
 
 -- | Vector space instance for tuples with four 'Floating' point numbers.
-instance (Eq a, Floating a) => VectorSpace (a,a,a,a) a where
-    zeroVector = (0,0,0,0)
+instance (Eq a, Floating a) => VectorSpace (a, a, a, a) a where
+  zeroVector = (0, 0, 0, 0)
 
-    a *^ (x,y,z,u) = (a * x, a * y, a * z, a * u)
+  a *^ (x, y, z, u) = (a * x, a * y, a * z, a * u)
 
-    (x,y,z,u) ^/ a = (x / a, y / a, z / a, u / a)
+  (x, y, z, u) ^/ a = (x / a, y / a, z / a, u / a)
 
-    negateVector (x,y,z,u) = (-x, -y, -z, -u)
+  negateVector (x, y, z, u) = (-x, -y, -z, -u)
 
-    (x1,y1,z1,u1) ^+^ (x2,y2,z2,u2) = (x1+x2, y1+y2, z1+z2, u1+u2)
+  (x1, y1, z1, u1) ^+^ (x2, y2, z2, u2) = (x1 + x2, y1 + y2, z1 + z2, u1 + u2)
 
-    (x1,y1,z1,u1) ^-^ (x2,y2,z2,u2) = (x1-x2, y1-y2, z1-z2, u1-u2)
+  (x1, y1, z1, u1) ^-^ (x2, y2, z2, u2) = (x1 - x2, y1 - y2, z1 - z2, u1 - u2)
 
-    (x1,y1,z1,u1) `dot` (x2,y2,z2,u2) = x1 * x2 + y1 * y2 + z1 * z2 + u1 * u2
+  (x1, y1, z1, u1) `dot` (x2, y2, z2, u2) =
+    x1 * x2 + y1 * y2 + z1 * z2 + u1 * u2
 
 -- | Vector space instance for tuples with five 'Floating' point numbers.
-instance (Eq a, Floating a) => VectorSpace (a,a,a,a,a) a where
-    zeroVector = (0,0,0,0,0)
+instance (Eq a, Floating a) => VectorSpace (a, a, a, a, a) a where
+  zeroVector = (0, 0, 0, 0, 0)
 
-    a *^ (x,y,z,u,v) = (a * x, a * y, a * z, a * u, a * v)
+  a *^ (x, y, z, u, v) = (a * x, a * y, a * z, a * u, a * v)
 
-    (x,y,z,u,v) ^/ a = (x / a, y / a, z / a, u / a, v / a)
+  (x, y, z, u, v) ^/ a = (x / a, y / a, z / a, u / a, v / a)
 
-    negateVector (x,y,z,u,v) = (-x, -y, -z, -u, -v)
+  negateVector (x, y, z, u, v) = (-x, -y, -z, -u, -v)
 
-    (x1,y1,z1,u1,v1) ^+^ (x2,y2,z2,u2,v2) = (x1+x2, y1+y2, z1+z2, u1+u2, v1+v2)
+  (x1, y1, z1, u1, v1) ^+^ (x2, y2, z2, u2, v2) =
+    (x1 + x2, y1 + y2, z1 + z2, u1 + u2, v1 + v2)
 
-    (x1,y1,z1,u1,v1) ^-^ (x2,y2,z2,u2,v2) = (x1-x2, y1-y2, z1-z2, u1-u2, v1-v2)
+  (x1, y1, z1, u1, v1) ^-^ (x2, y2, z2, u2, v2) =
+    (x1 - x2, y1 - y2, z1 - z2, u1 - u2, v1 - v2)
 
-    (x1,y1,z1,u1,v1) `dot` (x2,y2,z2,u2,v2) =
-        x1 * x2 + y1 * y2 + z1 * z2 + u1 * u2 + v1 * v2
+  (x1, y1, z1, u1, v1) `dot` (x2, y2, z2, u2, v2) =
+    x1 * x2 + y1 * y2 + z1 * z2 + u1 * u2 + v1 * v2
