diff --git a/coordinate.cabal b/coordinate.cabal
--- a/coordinate.cabal
+++ b/coordinate.cabal
@@ -1,5 +1,5 @@
 name:               coordinate
-version:            0.0.2
+version:            0.0.3
 license:            BSD3
 license-File:       etc/LICENCE
 author:             Tony Morris <ʇǝu˙sıɹɹoɯʇ@ןןǝʞsɐɥ>
diff --git a/src/Data/GPS/Coordinate/Coordinate.hs b/src/Data/GPS/Coordinate/Coordinate.hs
--- a/src/Data/GPS/Coordinate/Coordinate.hs
+++ b/src/Data/GPS/Coordinate/Coordinate.hs
@@ -8,7 +8,7 @@
 , coordinateDMSLatDMSLon
 ) where
 
-import Prelude(Eq, Show, id, (.))
+import Prelude(Eq, Show, Ord, id, (.))
 import Control.Lens(Iso', Lens', iso, lens, mapping, swapped, withIso)
 import Data.GPS.Coordinate.Latitude
 import Data.GPS.Coordinate.Longitude
@@ -21,7 +21,7 @@
   Coordinate
     Latitude
     Longitude
-  deriving (Eq, Show)
+  deriving (Eq, Ord, Show)
 
 coordinateLatLon ::
   Iso' (Latitude, Longitude) Coordinate
diff --git a/src/Data/GPS/Coordinate/DegreesLatitude.hs b/src/Data/GPS/Coordinate/DegreesLatitude.hs
--- a/src/Data/GPS/Coordinate/DegreesLatitude.hs
+++ b/src/Data/GPS/Coordinate/DegreesLatitude.hs
@@ -8,16 +8,42 @@
 import Data.Maybe(Maybe(..))
 import Control.Lens(Prism', Lens', prism')
 
+-- $setup
+-- >>> import Control.Lens((#), (^?))
+-- >>> import Data.Foldable(all)
+-- >>> import Prelude(Eq(..))
+
 newtype DegreesLatitude =
   DegreesLatitude Int
-  deriving (Eq, Show)
+  deriving (Eq, Ord, Show)
 
+-- | A prism on degrees latitude to an integer between -90 and 90 exclusive.
+--
+-- >>> 7 ^? nDegreesLatitude
+-- Just (DegreesLatitude 7)
+--
+-- >>> 0 ^? nDegreesLatitude
+-- Just (DegreesLatitude 0)
+--
+-- >>> 89 ^? nDegreesLatitude
+-- Just (DegreesLatitude 89)
+--
+-- >>> 90 ^? nDegreesLatitude
+-- Nothing
+--
+-- >>> (-89) ^? nDegreesLatitude
+-- Just (DegreesLatitude (-89))
+--
+-- >>> (-90) ^? nDegreesLatitude
+-- Nothing
+--
+-- prop> all (\m -> nDegreesLatitude # m == n) (n ^? nDegreesLatitude)
 nDegreesLatitude ::
   Prism' Int DegreesLatitude
 nDegreesLatitude =
   prism'
     (\(DegreesLatitude i) -> i)
-    (\i -> case i >= -90 && i <= 90 of
+    (\i -> case i > -90 && i < 90 of
              True -> Just (DegreesLatitude i)
              False -> Nothing)
 
diff --git a/src/Data/GPS/Coordinate/DegreesLongitude.hs b/src/Data/GPS/Coordinate/DegreesLongitude.hs
--- a/src/Data/GPS/Coordinate/DegreesLongitude.hs
+++ b/src/Data/GPS/Coordinate/DegreesLongitude.hs
@@ -8,16 +8,42 @@
 import Data.Maybe(Maybe(..))
 import Control.Lens(Prism', Lens', prism')
 
+-- $setup
+-- >>> import Control.Lens((#), (^?))
+-- >>> import Data.Foldable(all)
+-- >>> import Prelude(Eq(..))
+
 newtype DegreesLongitude =
   DegreesLongitude Int
-  deriving (Eq, Show)
+  deriving (Eq, Ord, Show)
 
+-- | A prism on degrees longitude to an integer between -180 and 180 exclusive.
+--
+-- >>> 7 ^? nDegreesLongitude
+-- Just (DegreesLongitude 7)
+--
+-- >>> 0 ^? nDegreesLongitude
+-- Just (DegreesLongitude 0)
+--
+-- >>> 179 ^? nDegreesLongitude
+-- Just (DegreesLongitude 179)
+--
+-- >>> 180 ^? nDegreesLongitude
+-- Nothing
+--
+-- >>> (-179) ^? nDegreesLongitude
+-- Just (DegreesLongitude (-179))
+--
+-- >>> (-180) ^? nDegreesLongitude
+-- Nothing
+--
+-- prop> all (\m -> nDegreesLongitude # m == n) (n ^? nDegreesLongitude)
 nDegreesLongitude ::
   Prism' Int DegreesLongitude
 nDegreesLongitude  =
   prism'
     (\(DegreesLongitude i) -> i)
-    (\i -> case i >= -180 && i <= 180 of
+    (\i -> case i > -180 && i < 180 of
              True -> Just (DegreesLongitude i)
              False -> Nothing)
 
diff --git a/src/Data/GPS/Coordinate/Latitude.hs b/src/Data/GPS/Coordinate/Latitude.hs
--- a/src/Data/GPS/Coordinate/Latitude.hs
+++ b/src/Data/GPS/Coordinate/Latitude.hs
@@ -11,18 +11,71 @@
 import Data.GPS.Coordinate.Minutes
 import Data.GPS.Coordinate.Seconds
 
+-- $setup
+-- >>> import Control.Lens((^?))
+
 data Latitude =
   Latitude
     DegreesLatitude
     Minutes
     Seconds
-  deriving (Eq, Show)
+  deriving (Eq, Ord, Show)
 
+-- | An isomorphism on the triple of degrees latitude, minutes, seconds to a latitude.
+--
+-- >>> do deg <- 7 ^? nDegreesLatitude; min <- 7 ^? nMinutes; sec <- 7 ^? nSeconds; (deg, min, sec) ^? dmsLatitude
+-- Just (Latitude (DegreesLatitude 7) (Minutes 7) (Seconds 7.0000))
+--
+-- >>> do deg <- 89 ^? nDegreesLatitude; min <- 59 ^? nMinutes; sec <- 59 ^? nSeconds; (deg, min, sec) ^? dmsLatitude
+-- Just (Latitude (DegreesLatitude 89) (Minutes 59) (Seconds 59.0000))
+--
+-- >>> do deg <- (-7) ^? nDegreesLatitude; min <- 7 ^? nMinutes; sec <- 7 ^? nSeconds; (deg, min, sec) ^? dmsLatitude
+-- Just (Latitude (DegreesLatitude (-7)) (Minutes 7) (Seconds 7.0000))
+--
+-- >>> do deg <- (-89) ^? nDegreesLatitude; min <- 59 ^? nMinutes; sec <- 59 ^? nSeconds; (deg, min, sec) ^? dmsLatitude
+-- Just (Latitude (DegreesLatitude (-89)) (Minutes 59) (Seconds 59.0000))
+--
+-- >>> do deg <- 90 ^? nDegreesLatitude; min <- 59 ^? nMinutes; sec <- 59 ^? nSeconds; (deg, min, sec) ^? dmsLatitude
+-- Nothing
+--
+-- >>> do deg <- 89 ^? nDegreesLatitude; min <- 60 ^? nMinutes; sec <- 59 ^? nSeconds; (deg, min, sec) ^? dmsLatitude
+-- Nothing
+--
+-- >>> do deg <- 89 ^? nDegreesLatitude; min <- 59 ^? nMinutes; sec <- 60 ^? nSeconds; (deg, min, sec) ^? dmsLatitude
+-- Nothing
 dmsLatitude ::
   Iso' (DegreesLatitude, Minutes, Seconds) Latitude
 dmsLatitude =
   iso (\(d, m, s) -> Latitude d m s) (\(Latitude d m s) -> (d, m, s))
 
+-- | A prism on latitude to a double between -90 and 90 inclusive.
+--
+-- >>> 7 ^? fracLatitude
+-- Just (Latitude (DegreesLatitude 7) (Minutes 0) (Seconds 0.0000))
+--
+-- >>> (-7) ^? fracLatitude
+-- Just (Latitude (DegreesLatitude (-7)) (Minutes 0) (Seconds 0.0000))
+--
+-- >>> 7.12 ^? fracLatitude
+-- Just (Latitude (DegreesLatitude 7) (Minutes 7) (Seconds 12.0000))
+--
+-- >>> (-7.12) ^? fracLatitude
+-- Just (Latitude (DegreesLatitude (-7)) (Minutes 7) (Seconds 12.0000))
+--
+-- >>> 90 ^? fracLatitude
+-- Nothing
+--
+-- >>> (-90) ^? fracLatitude
+-- Nothing
+--
+-- >>> 15.63791 ^? fracLatitude
+-- Just (Latitude (DegreesLatitude 15) (Minutes 38) (Seconds 16.4760))
+--
+-- >>> 89.1 ^? fracLatitude
+-- Just (Latitude (DegreesLatitude 89) (Minutes 5) (Seconds 60.0000))
+--
+-- >>> 89.2 ^? fracLatitude
+-- Just (Latitude (DegreesLatitude 89) (Minutes 12) (Seconds 0.0000))
 fracLatitude ::
   Prism' Double Latitude
 fracLatitude =
@@ -31,8 +84,8 @@
     (\x -> let (d, z) = properFraction x
                (m, s) = properFraction ((z :: Double) * 60)
            in do d' <- d ^? nDegreesLatitude
-                 m' <- m ^? nMinutes
-                 s' <- s ^? nSeconds
+                 m' <- abs m ^? nMinutes
+                 s' <- (abs s * 60) ^? nSeconds
                  return (Latitude d' m' s'))
 
 class HasLatitude t where
diff --git a/src/Data/GPS/Coordinate/Longitude.hs b/src/Data/GPS/Coordinate/Longitude.hs
--- a/src/Data/GPS/Coordinate/Longitude.hs
+++ b/src/Data/GPS/Coordinate/Longitude.hs
@@ -16,13 +16,63 @@
     DegreesLongitude
     Minutes
     Seconds
-  deriving (Eq, Show)
+  deriving (Eq, Ord, Show)
 
+-- | An isomorphism on the triple of degrees longitude, minutes, seconds to a longitude.
+--
+-- >>> do deg <- 7 ^? nDegreesLongitude; min <- 7 ^? nMinutes; sec <- 7 ^? nSeconds; (deg, min, sec) ^? dmsLongitude
+-- Just (Longitude (DegreesLongitude 7) (Minutes 7) (Seconds 7.0000))
+--
+-- >>> do deg <- 179 ^? nDegreesLongitude; min <- 59 ^? nMinutes; sec <- 59 ^? nSeconds; (deg, min, sec) ^? dmsLongitude
+-- Just (Longitude (DegreesLongitude 179) (Minutes 59) (Seconds 59.0000))
+--
+-- >>> do deg <- (-7) ^? nDegreesLongitude; min <- 7 ^? nMinutes; sec <- 7 ^? nSeconds; (deg, min, sec) ^? dmsLongitude
+-- Just (Longitude (DegreesLongitude (-7)) (Minutes 7) (Seconds 7.0000))
+--
+-- >>> do deg <- (-179) ^? nDegreesLongitude; min <- 59 ^? nMinutes; sec <- 59 ^? nSeconds; (deg, min, sec) ^? dmsLongitude
+-- Just (Longitude (DegreesLongitude (-179)) (Minutes 59) (Seconds 59.0000))
+--
+-- >>> do deg <- 180 ^? nDegreesLongitude; min <- 59 ^? nMinutes; sec <- 59 ^? nSeconds; (deg, min, sec) ^? dmsLongitude
+-- Nothing
+--
+-- >>> do deg <- 179 ^? nDegreesLongitude; min <- 60 ^? nMinutes; sec <- 59 ^? nSeconds; (deg, min, sec) ^? dmsLongitude
+-- Nothing
+--
+-- >>> do deg <- 179 ^? nDegreesLongitude; min <- 59 ^? nMinutes; sec <- 60 ^? nSeconds; (deg, min, sec) ^? dmsLongitude
+-- Nothing
 dmsLongitude ::
   Iso' (DegreesLongitude, Minutes, Seconds) Longitude
 dmsLongitude =
   iso (\(d, m, s) -> Longitude d m s) (\(Longitude d m s) -> (d, m, s))
 
+-- | A prism on longitude to a double between -180 and 180 inclusive.
+--
+-- >>> 7 ^? fracLongitude
+-- Just (Longitude (DegreesLongitude 7) (Minutes 0) (Seconds 0.0000))
+--
+-- >>> (-7) ^? fracLongitude
+-- Just (Longitude (DegreesLongitude (-7)) (Minutes 0) (Seconds 0.0000))
+--
+-- >>> 7.12 ^? fracLongitude
+-- Just (Longitude (DegreesLongitude 7) (Minutes 7) (Seconds 12.0000))
+--
+-- >>> (-7.12) ^? fracLongitude
+-- Just (Longitude (DegreesLongitude (-7)) (Minutes 7) (Seconds 12.0000))
+--
+-- >>> 180 ^? fracLongitude
+-- Nothing
+--
+-- >>> (-180) ^? fracLongitude
+-- Nothing
+--
+-- >>> 15.63791 ^? fracLongitude
+-- Just (Longitude (DegreesLongitude 15) (Minutes 38) (Seconds 16.4760))
+--
+-- >>> 179.1 ^? fracLongitude
+-- Just (Longitude (DegreesLongitude 179) (Minutes 5) (Seconds 60.0000))
+--
+-- >>> 179.2 ^? fracLongitude
+-- Just (Longitude (DegreesLongitude 179) (Minutes 11) (Seconds 60.0000))
 fracLongitude ::
   Prism' Double Longitude
 fracLongitude =
@@ -31,8 +81,8 @@
     (\x -> let (d, z) = properFraction x
                (m, s) = properFraction ((z :: Double) * 60)
            in do d' <- d ^? nDegreesLongitude
-                 m' <- m ^? nMinutes
-                 s' <- s ^? nSeconds
+                 m' <- abs m ^? nMinutes
+                 s' <- (abs s * 60) ^? nSeconds
                  return (Longitude d' m' s'))
 
 class HasLongitude t where
diff --git a/src/Data/GPS/Coordinate/Minutes.hs b/src/Data/GPS/Coordinate/Minutes.hs
--- a/src/Data/GPS/Coordinate/Minutes.hs
+++ b/src/Data/GPS/Coordinate/Minutes.hs
@@ -8,10 +8,30 @@
 import Data.Maybe(Maybe(..))
 import Control.Lens(Prism', Lens', prism')
 
+-- $setup
+-- >>> import Control.Lens((#), (^?))
+-- >>> import Data.Foldable(all)
+-- >>> import Prelude(Eq(..))
+
 newtype Minutes =
   Minutes Int
-  deriving (Eq, Show)
+  deriving (Eq, Ord, Show)
 
+-- | A prism on minutes to an integer between 0 and 59 inclusive.
+--
+-- >>> 7 ^? nMinutes
+-- Just (Minutes 7)
+--
+-- >>> 0 ^? nMinutes
+-- Just (Minutes 0)
+--
+-- >>> 59 ^? nMinutes
+-- Just (Minutes 59)
+--
+-- >>> 60 ^? nMinutes
+-- Nothing
+--
+-- prop> all (\m -> nMinutes # m == n) (n ^? nMinutes)
 nMinutes ::
   Prism' Int Minutes
 nMinutes =
diff --git a/src/Data/GPS/Coordinate/Seconds.hs b/src/Data/GPS/Coordinate/Seconds.hs
--- a/src/Data/GPS/Coordinate/Seconds.hs
+++ b/src/Data/GPS/Coordinate/Seconds.hs
@@ -4,14 +4,44 @@
 , nSeconds
 ) where
 
-import Prelude(Double, Bool(..), Eq, Show, Ord(..), id, (&&))
+import Prelude(Double, Bool(..), Eq, Show(..), Ord(..), id, (&&), (++), showParen, showString)
 import Data.Maybe(Maybe(..))
 import Control.Lens(Prism', Lens', prism')
+import Text.Printf(printf)
 
+-- $setup
+-- >>> import Control.Lens((#), (^?))
+-- >>> import Data.Foldable(all)
+-- >>> import Prelude(Eq(..))
+
 newtype Seconds =
   Seconds Double
-  deriving (Eq, Show)
+  deriving (Eq, Ord)
 
+-- | A show instance that prints to 4 decimal places.
+-- This is to take floating-point rounding errors into account.
+instance Show Seconds where
+  showsPrec n (Seconds d) =
+    showParen (n > 10) (showString ("Seconds " ++ printf "%0.4f" d))
+
+-- | A prism on seconds to a double between 0 inclusive and 60 exclusive.
+--
+-- >>> 7 ^? nSeconds
+-- Just (Seconds 7.0000)
+--
+-- >>> 0 ^? nSeconds
+-- Just (Seconds 0.0000)
+--
+-- >>> 59 ^? nSeconds
+-- Just (Seconds 59.0000)
+--
+-- >>> 59.99 ^? nSeconds
+-- Just (Seconds 59.9900)
+--
+-- >>> 60 ^? nSeconds
+-- Nothing
+--
+-- prop> all (\m -> nSeconds # m == n) (n ^? nSeconds)
 nSeconds ::
   Prism' Double Seconds
 nSeconds =
