diff --git a/lib/Data/Locator.hs b/lib/Data/Locator.hs
--- a/lib/Data/Locator.hs
+++ b/lib/Data/Locator.hs
@@ -1,16 +1,3 @@
---
--- Human exchangable identifiers and locators
---
--- Copyright © 2011-2018 Operational Dynamics Consulting, Pty Ltd
---
--- The code in this file, and the program it is a part of, is
--- made available to you by its authors as open source software:
--- you can redistribute it and/or modify it under the terms of
--- the BSD licence.
---
--- This code originally licenced GPLv2. Relicenced BSD3 on 2 Jan 2014.
---
-
 {-# LANGUAGE OverloadedStrings #-}
 
 --
diff --git a/lib/Data/Locator/Common.hs b/lib/Data/Locator/Common.hs
--- a/lib/Data/Locator/Common.hs
+++ b/lib/Data/Locator/Common.hs
@@ -1,30 +1,18 @@
---
--- Human exchangable identifiers and locators
---
--- Copyright © 2011-2018 Operational Dynamics Consulting, Pty Ltd
---
--- The code in this file, and the program it is a part of, is
--- made available to you by its authors as open source software:
--- you can redistribute it and/or modify it under the terms of
--- the BSD licence.
---
--- This code originally licenced GPLv2. Relicenced BSD3 on 2 Jan 2014.
---
+{-# LANGUAGE InstanceSigs #-}
 {-# LANGUAGE OverloadedStrings #-}
 {-# LANGUAGE ScopedTypeVariables #-}
-{-# LANGUAGE InstanceSigs #-}
 {-# LANGUAGE TypeApplications #-}
 
-module Data.Locator.Common
-  ( Locator(..)
-  , represent
-  , value
-  , toLocatorUnique
-  , multiply
-  , fromLocator
-  , concatToInteger
-  , digest
-  ) where
+module Data.Locator.Common (
+    Locator (..),
+    represent,
+    value,
+    toLocatorUnique,
+    multiply,
+    fromLocator,
+    concatToInteger,
+    digest,
+) where
 
 import Prelude hiding (toInteger)
 
@@ -40,7 +28,6 @@
     locatorToDigit :: α -> Char
     digitToLocator :: Char -> α
 
-
 represent :: Locator α => α -> Int -> Char
 represent (_ :: α) n =
     locatorToDigit $ (toEnum n :: α)
@@ -56,41 +43,39 @@
     fromEnum $ (digitToLocator c :: α)
 
 --
--- | Represent a number in Locator16a format. This uses the Locator16 symbol
--- set, and additionally specifies that no symbol can be repeated. The /a/ in
--- Locator16a represents that this transformation is done on the cheap; when
--- converting if we end up with \'9\' \'9\' we simply pick the subsequent digit
--- in the enum, in this case getting you \'9\' \'K\'.
---
--- Note that the transformation is /not/ reversible. A number like @4369@
--- (which is @0x1111@, incidentally) encodes as @12C4@. So do @4370@, @4371@,
--- and @4372@. The point is not uniqueness, but readibility in adverse
--- conditions. So while you can count locators, they don't map continuously to
--- base10 integers.
---
--- The first argument is the number of digits you'd like in the locator; if the
--- number passed in is less than 16^limit, then the result will be padded.
---
--- >>> toLocator16a 6 4369
--- 12C40F
---
+
+{- |
+Represent a number in Locator16a format. This uses the Locator16 symbol
+set, and additionally specifies that no symbol can be repeated. The /a/ in
+Locator16a represents that this transformation is done on the cheap; when
+converting if we end up with \'9\' \'9\' we simply pick the subsequent digit
+in the enum, in this case getting you \'9\' \'K\'.
+
+Note that the transformation is /not/ reversible. A number like @4369@
+(which is @0x1111@, incidentally) encodes as @12C4@. So do @4370@, @4371@,
+and @4372@. The point is not uniqueness, but readibility in adverse
+conditions. So while you can count locators, they don't map continuously to
+base10 integers.
+
+The first argument is the number of digits you'd like in the locator; if the
+number passed in is less than 16^limit, then the result will be padded.
+
+>>> toLocator16a 6 4369
+12C40F
+-}
 toLocatorUnique :: Locator α => Int -> Int -> α -> String
 toLocatorUnique limit n (_ :: α) =
-  let
-    n' = abs n
-    ls = convert n' (replicate limit (minBound @α))
-    (_,us) = mapAccumL uniq Set.empty ls
-  in
-    map locatorToDigit (take limit us)
+    let n' = abs n
+        ls = convert n' (replicate limit (minBound @α))
+        (_, us) = mapAccumL uniq Set.empty ls
+     in map locatorToDigit (take limit us)
   where
     convert :: Locator α => Int -> [α] -> [α]
     convert 0 xs = xs
     convert i xs =
-      let
-        (d,r) = divMod i 16
-        x = toEnum r
-      in
-        convert d (x:xs)
+        let (d, r) = divMod i 16
+            x = toEnum r
+         in convert d (x : xs)
 
     uniq :: Locator α => Set α -> α -> (Set α, α)
     uniq s x =
@@ -106,14 +91,12 @@
 
 multiply :: Locator α => α -> Int -> Char -> Int
 multiply (locator :: a) acc c =
-  let
-    base = fromEnum (maxBound @a) + 1
-  in
-    (acc * base) + (value locator c)
+    let base = fromEnum (maxBound @a) + 1
+     in (acc * base) + (value locator c)
 
 --
+
 -- | Given a number encoded as a Locator, convert it back to an integer.
---
 fromLocator :: Locator α => α -> String -> Int
 fromLocator locator ss =
     foldl (multiply locator) 0 ss
@@ -131,8 +114,7 @@
 digest ws =
     i
   where
-    i  = concatToInteger h
-    h  = B.unpack h'
+    i = concatToInteger h
+    h = B.unpack h'
     h' = Crypto.hash x' :: Crypto.Digest Crypto.SHA1
     x' = S.pack ws
-
diff --git a/lib/Data/Locator/English16.hs b/lib/Data/Locator/English16.hs
--- a/lib/Data/Locator/English16.hs
+++ b/lib/Data/Locator/English16.hs
@@ -1,34 +1,21 @@
---
--- Human exchangable identifiers and locators
---
--- Copyright © 2011-2018 Operational Dynamics Consulting, Pty Ltd
---
--- The code in this file, and the program it is a part of, is
--- made available to you by its authors as open source software:
--- you can redistribute it and/or modify it under the terms of
--- the BSD licence.
---
--- This code originally licenced GPLv2. Relicenced BSD3 on 2 Jan 2014.
---
+{-# LANGUAGE InstanceSigs #-}
 {-# LANGUAGE OverloadedStrings #-}
 {-# LANGUAGE ScopedTypeVariables #-}
-{-# LANGUAGE InstanceSigs #-}
 {-# LANGUAGE TypeApplications #-}
 
-module Data.Locator.English16
-  ( Locator(..)
-  , English16(..)
-  , fromEnglish16
-  , toEnglish16
-  , toEnglish16a
-  , hashStringToEnglish16a
-
+module Data.Locator.English16 (
+    Locator (..),
+    English16 (..),
+    fromEnglish16,
+    toEnglish16,
+    toEnglish16a,
+    hashStringToEnglish16a,
     -- Deprecated
-  , fromLocator16
-  , toLocator16
-  , toLocator16a
-  , hashStringToLocator16a
-  ) where
+    fromLocator16,
+    toLocator16,
+    toLocator16a,
+    hashStringToLocator16a,
+) where
 
 import Prelude hiding (toInteger)
 
@@ -42,20 +29,23 @@
 import Data.Locator.Common
 
 --
--- | A symbol set with sixteen uniquely pronounceable digits.
---
--- The fact there are sixteen symbols is more an indication of a certain degree
--- of bullheaded-ness on the part of the author, and less of any kind of actual
--- requirement. We might have a slighly better readback score if we dropped to
--- 15 or 14 unique characters. It does mean you can match up with hexidecimal,
--- which is not entirely without merit.
---
--- The grouping of letters and numbers was the hard part; having come up with
--- the set and deconflicted the choices, the ordering is then entirely
--- arbitrary. Since there are some numbers, might as well have them at the same
--- place they correspond to in base 10; the letters were then allocated in
--- alpha order in the remaining slots.
---
+
+{- |
+A symbol set with sixteen uniquely pronounceable digits.
+
+The fact there are sixteen symbols is more an indication of a certain degree
+of bullheaded-ness on the part of the author, and less of any kind of actual
+requirement. We might have a slighly better readback score if we dropped to
+15 or 14 unique characters. It does mean you can match up with hexidecimal,
+which is not entirely without merit.
+
+The grouping of letters and numbers was the hard part; having come up with
+the set and deconflicted the choices, the ordering is then entirely
+arbitrary. Since there are some numbers, might as well have them at the same
+place they correspond to in base 10; the letters were then allocated in alpha
+order in the remaining slots.
+-}
+
 {-
         -- 0 Conflicts with @\'O\'@ obviously, and @\'Q\'@ often enough
         --
@@ -90,44 +80,60 @@
         -- usual reason of being similar to @\'1\'@.
 -}
 data English16
-    = Zero      -- ^ @\'0\'@ /0th/
-    | One       -- ^ @\'1\'@ /1st/
-    | Two       -- ^ @\'2\'@ /2nd/
-    | Charlie   -- ^ @\'C\'@ /3rd/
-    | Four      -- ^ @\'4\'@ /4th/
-    | Foxtrot   -- ^ @\'F\'@ /5th/
-    | Hotel     -- ^ @\'H\'@ /6th/
-    | Seven     -- ^ @\'7\'@ /7th/
-    | Eight     -- ^ @\'8\'@ /8th/
-    | Nine      -- ^ @\'9\'@ /9th/
-    | Kilo      -- ^ @\'K\'@ /10th/
-    | Lima      -- ^ @\'L\'@ /11th/
-    | Mike      -- ^ @\'M\'@ /12th/
-    | Romeo     -- ^ @\'R\'@ /13th/
-    | XRay      -- ^ @\'X\'@ /14th/
-    | Yankee    -- ^ @\'Y\'@ /15th/
+    = -- | @\'0\'@ /0th/
+      Zero
+    | -- | @\'1\'@ /1st/
+      One
+    | -- | @\'2\'@ /2nd/
+      Two
+    | -- | @\'C\'@ /3rd/
+      Charlie
+    | -- | @\'4\'@ /4th/
+      Four
+    | -- | @\'F\'@ /5th/
+      Foxtrot
+    | -- | @\'H\'@ /6th/
+      Hotel
+    | -- | @\'7\'@ /7th/
+      Seven
+    | -- | @\'8\'@ /8th/
+      Eight
+    | -- | @\'9\'@ /9th/
+      Nine
+    | -- | @\'K\'@ /10th/
+      Kilo
+    | -- | @\'L\'@ /11th/
+      Lima
+    | -- | @\'M\'@ /12th/
+      Mike
+    | -- | @\'R\'@ /13th/
+      Romeo
+    | -- | @\'X\'@ /14th/
+      XRay
+    | -- | @\'Y\'@ /15th/
+      Yankee
     deriving (Eq, Ord, Enum, Bounded)
 
 instance Locator English16 where
     locatorToDigit :: English16 -> Char
     locatorToDigit x =
         case x of
-            Zero    -> '0'
-            One     -> '1'
-            Two     -> '2'
+            Zero -> '0'
+            One -> '1'
+            Two -> '2'
             Charlie -> 'C'
-            Four    -> '4'
+            Four -> '4'
             Foxtrot -> 'F'
-            Hotel   -> 'H'
-            Seven   -> '7'
-            Eight   -> '8'
-            Nine    -> '9'
-            Kilo    -> 'K'
-            Lima    -> 'L'
-            Mike    -> 'M'
-            Romeo   -> 'R'
-            XRay    -> 'X'
-            Yankee  -> 'Y'
+            Hotel -> 'H'
+            Seven -> '7'
+            Eight -> '8'
+            Nine -> '9'
+            Kilo -> 'K'
+            Lima -> 'L'
+            Mike -> 'M'
+            Romeo -> 'R'
+            XRay -> 'X'
+            Yankee -> 'Y'
 
     digitToLocator :: Char -> English16
     digitToLocator c =
@@ -148,7 +154,7 @@
             'R' -> Romeo
             'X' -> XRay
             'Y' -> Yankee
-            _   -> error "Illegal digit"
+            _ -> error "Illegal digit"
 
 instance Show English16 where
     show x = [c]
@@ -156,54 +162,54 @@
         c = locatorToDigit x
 
 --
--- | Given a number, convert it to a string in the English16 base 16 symbol
--- alphabet. You can use this as a replacement for the standard \'0\'-\'9\'
--- \'A\'-\'F\' symbols traditionally used to express hexidemimal, though really
--- the fact that we came up with 16 total unique symbols was a nice
--- co-incidence, not a requirement.
---
+
+{- |
+Given a number, convert it to a string in the English16 base 16 symbol
+alphabet. You can use this as a replacement for the standard \'0\'-\'9\'
+\'A\'-\'F\' symbols traditionally used to express hexidemimal, though really
+the fact that we came up with 16 total unique symbols was a nice
+co-incidence, not a requirement.
+-}
 toEnglish16 :: Int -> String
 toEnglish16 x =
     showIntAtBase 16 (represent Yankee) x ""
 
 --
--- | Represent a number in English16a format. This uses the Locator16 symbol
--- set, and additionally specifies that no symbol can be repeated. The /a/ in
--- Locator16a represents that this transformation is done on the cheap; when
--- converting if we end up with \'9\' \'9\' we simply pick the subsequent digit
--- in the enum, in this case getting you \'9\' \'K\'.
---
--- Note that the transformation is /not/ reversible. A number like @4369@
--- (which is @0x1111@, incidentally) encodes as @12C4@. So do @4370@, @4371@,
--- and @4372@. The point is not uniqueness, but readibility in adverse
--- conditions. So while you can count locators, they don't map continuously to
--- base10 integers.
---
--- The first argument is the number of digits you'd like in the locator; if the
--- number passed in is less than 16^limit, then the result will be padded.
---
--- >>> toEnglish16a 6 4369
--- 12C40F
---
+
+{- |
+Represent a number in English16a format. This uses the Locator16 symbol
+set, and additionally specifies that no symbol can be repeated. The /a/ in
+Locator16a represents that this transformation is done on the cheap; when
+converting if we end up with \'9\' \'9\' we simply pick the subsequent digit
+in the enum, in this case getting you \'9\' \'K\'.
+
+Note that the transformation is /not/ reversible. A number like @4369@
+(which is @0x1111@, incidentally) encodes as @12C4@. So do @4370@, @4371@,
+and @4372@. The point is not uniqueness, but readibility in adverse
+conditions. So while you can count locators, they don't map continuously to
+base10 integers.
+
+The first argument is the number of digits you'd like in the locator; if the
+number passed in is less than 16^limit, then the result will be padded.
+
+>>> toEnglish16a 6 4369
+12C40F
+-}
 toEnglish16a :: Int -> Int -> String
 toEnglish16a limit n
-  | limit > 16 = error "Can only request a maximum of 16 English16a characters, not " ++ (show limit)
-  | otherwise  =
-  let
-    n' = abs n
-    ls = convert n' (replicate limit minBound)       :: [English16]
-    (_,us) = mapAccumL uniq Set.empty ls
-  in
-    map locatorToDigit (take limit us)
+    | limit > 16 = error "Can only request a maximum of 16 English16a characters, not " ++ (show limit)
+    | otherwise =
+        let n' = abs n
+            ls = convert n' (replicate limit minBound) :: [English16]
+            (_, us) = mapAccumL uniq Set.empty ls
+         in map locatorToDigit (take limit us)
   where
     convert :: Locator α => Int -> [α] -> [α]
     convert 0 xs = xs
     convert i xs =
-      let
-        (d,r) = divMod i 16
-        x = toEnum r
-      in
-        convert d (x:xs)
+        let (d, r) = divMod i 16
+            x = toEnum r
+         in convert d (x : xs)
 
     uniq :: Locator α => Set α -> α -> (Set α, α)
     uniq s x =
@@ -218,33 +224,32 @@
             else succ x
 
 --
+
 -- | Given a number encoded in Locator16, convert it back to an integer.
---
 fromEnglish16 :: [Char] -> Int
 fromEnglish16 ss =
     foldl (multiply Yankee) 0 ss
 
 --
--- | Take an arbitrary sequence of bytes, hash it with SHA1, then format as a
--- short @digits@-long Locator16 string.
---
--- >>> hashStringToLocator16a 6 "Hello World"
--- M48HR0
---
+
+{- |
+Take an arbitrary sequence of bytes, hash it with SHA1, then format as a
+short @digits@-long Locator16 string.
+
+>>> hashStringToLocator16a 6 "Hello World"
+M48HR0
+-}
 hashStringToEnglish16a :: Int -> ByteString -> ByteString
 hashStringToEnglish16a limit s' =
-  let
-    s  = S.unpack s'
-    n  = digest s               -- SHA1 hash
-    r  = mod n upperBound       -- trim to specified number of base 16 chars
-    x  = toLocator16a limit r   -- express in locator16
-    b' = S.pack x
-  in
-    b'
+    let s = S.unpack s'
+        n = digest s -- SHA1 hash
+        r = mod n upperBound -- trim to specified number of base 16 chars
+        x = toLocator16a limit r -- express in locator16
+        b' = S.pack x
+     in b'
   where
     upperBound = 16 ^ limit
 
-
 toLocator16 :: Int -> String
 toLocator16 = toEnglish16
 {-# DEPRECATED toLocator16 "Use toEnglish16 instead" #-}
@@ -256,7 +261,6 @@
 fromLocator16 :: [Char] -> Int
 fromLocator16 = fromEnglish16
 {-# DEPRECATED fromLocator16 "Use fromEnglish16 instead" #-}
-
 
 hashStringToLocator16a :: Int -> ByteString -> ByteString
 hashStringToLocator16a = hashStringToEnglish16a
diff --git a/lib/Data/Locator/Hashes.hs b/lib/Data/Locator/Hashes.hs
--- a/lib/Data/Locator/Hashes.hs
+++ b/lib/Data/Locator/Hashes.hs
@@ -1,26 +1,12 @@
---
--- Human exchangable identifiers and locators
---
--- Copyright © 2011-2017 Operational Dynamics Consulting, Pty Ltd
---
--- The code in this file, and the program it is a part of, is
--- made available to you by its authors as open source software:
--- you can redistribute it and/or modify it under the terms of
--- the BSD licence.
---
--- This code originally licenced GPLv2. Relicenced BSD3 on 2 Jan 2014.
---
-
 {-# LANGUAGE OverloadedStrings #-}
 
 module Data.Locator.Hashes (
     toBase62,
     fromBase62,
     padWithZeros,
-    hashStringToBase62
+    hashStringToBase62,
 ) where
 
-
 import Prelude hiding (toInteger)
 
 import Crypto.Hash as Crypto
@@ -47,13 +33,14 @@
     showIntAtBase 62 represent x ""
 
 --
--- | Utility function to prepend \'0\' characters to a string representing a
--- number. This allows you to ensure a fixed width for numbers that are less
--- than the desired width in size. This comes up frequently when representing
--- numbers in other bases greater than 10 as they are inevitably presented as
--- text, and not having them evenly justified can (at best) be ugly and (at
--- worst) actually lead to parsing and conversion bugs.
---
+
+{- | Utility function to prepend \'0\' characters to a string representing a
+ number. This allows you to ensure a fixed width for numbers that are less
+ than the desired width in size. This comes up frequently when representing
+ numbers in other bases greater than 10 as they are inevitably presented as
+ text, and not having them evenly justified can (at best) be ugly and (at
+ worst) actually lead to parsing and conversion bugs.
+-}
 padWithZeros :: Int -> String -> String
 padWithZeros digits str =
     pad ++ str
@@ -61,7 +48,6 @@
     pad = take len (replicate digits '0')
     len = digits - length str
 
-
 value :: Char -> Int
 value c
     | isDigit c = ord c - 48
@@ -77,43 +63,40 @@
 fromBase62 ss =
     foldl multiply 0 ss
 
-
 concatToInteger :: [Word8] -> Integer
 concatToInteger bytes =
     foldl fn 0 bytes
   where
     fn acc b = (acc * 256) + (fromIntegral b)
 
-
 digest :: String -> Integer
 digest ws =
     i
   where
-    i  = concatToInteger h
-    h  = B.unpack h'
+    i = concatToInteger h
+    h = B.unpack h'
     h' = Crypto.hash x' :: Crypto.Digest Crypto.SHA1
     x' = S.pack ws
 
-
 --
--- | Take an arbitrary string, hash it, then pad it with zeros up to be a
--- @digits@-long string in base 62.
---
--- You may be interested to know that the 160-bit SHA1 hash used here can be
--- expressed without loss as 27 digits of base 62, for example:
---
--- >>> hashStringToBase62 27 "Hello World"
--- 1T8Sj4C5jVU6iQXCwCwJEPSWX6u
---
+
+{- | Take an arbitrary string, hash it, then pad it with zeros up to be a
+ @digits@-long string in base 62.
+
+ You may be interested to know that the 160-bit SHA1 hash used here can be
+ expressed without loss as 27 digits of base 62, for example:
+
+ >>> hashStringToBase62 27 "Hello World"
+ 1T8Sj4C5jVU6iQXCwCwJEPSWX6u
+-}
 hashStringToBase62 :: Int -> ByteString -> ByteString
 hashStringToBase62 digits s' =
     r'
   where
     s = S.unpack s'
-    n  = digest s               -- SHA1 hash
+    n = digest s -- SHA1 hash
     limit = 62 ^ digits
-    x  = mod n limit            -- trim to specified number base62 chars
+    x = mod n limit -- trim to specified number base62 chars
     str = toBase62 x
-    r  = padWithZeros digits str  -- convert to String
+    r = padWithZeros digits str -- convert to String
     r' = S.pack r
-
diff --git a/lib/Data/Locator/Latin25.hs b/lib/Data/Locator/Latin25.hs
--- a/lib/Data/Locator/Latin25.hs
+++ b/lib/Data/Locator/Latin25.hs
@@ -1,26 +1,13 @@
---
--- Human exchangable identifiers and locators
---
--- Copyright © 2011-2018 Operational Dynamics Consulting, Pty Ltd
---
--- The code in this file, and the program it is a part of, is
--- made available to you by its authors as open source software:
--- you can redistribute it and/or modify it under the terms of
--- the BSD licence.
---
--- This code originally licenced GPLv2. Relicenced BSD3 on 2 Jan 2014.
---
-
-{-# LANGUAGE OverloadedStrings   #-}
-{-# LANGUAGE ScopedTypeVariables #-}
 {-# LANGUAGE InstanceSigs #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE ScopedTypeVariables #-}
 
-module Data.Locator.Latin25
-  ( Latin25(..)
-  , toLatin25
-  , fromLatin25
-  , hashStringToLatin25
-  ) where
+module Data.Locator.Latin25 (
+    Latin25 (..),
+    toLatin25,
+    fromLatin25,
+    hashStringToLatin25,
+) where
 
 import Prelude hiding (toInteger)
 
@@ -31,12 +18,13 @@
 import Data.Locator.Common
 import Data.Locator.Hashes (padWithZeros)
 
---
--- | A symbol set with twenty-five visually distinct characters.
---
--- These are not protected against similar pronounciations; if you need to
--- read your identifiers /aloud/ use 'English16' instead.
---
+{- |
+A symbol set with twenty-five visually distinct characters.
+
+These are not protected against similar pronounciations; if you need to
+read your identifiers /aloud/ use 'English16' instead.
+-}
+
 {-
 
     --  | Two       -- Obvious conflict with Z
@@ -44,7 +32,7 @@
     --  | Six       -- Too close to G
     --  | Bravo     -- Too close to 8
     --  | Delta     -- Shape of D too close to O
-    --  | Foxtrot   -- A bit close to E, and since we've included S, skip
+    --  | Foxtrot   -- Excluded because too close to E
     --  | India     -- Too close to 1 and J
     --  | Oscar     -- Obvious conflict with 0
     --  | Quebec    -- The tail on Q is too easy to miss, thereby colliding with O/0
@@ -53,61 +41,86 @@
 
 -}
 data Latin25
-    = Zero'     -- ^ @\'0\'@ /0th/
-    | One'      -- ^ @\'1\'@ /1st/
-    | Three'    -- ^ @\'3\'@ /2nd/
-    | Four'     -- ^ @\'4\'@ /3rd/
-    | Seven'    -- ^ @\'7\'@ /4th/
-    | Eight'    -- ^ @\'8\'@ /5th/
-    | Nine'     -- ^ @\'9\'@ /6th/
-    | Alpha'    -- ^ @\'A\'@ /7th/
-    | Charlie'  -- ^ @\'C\'@ /8th/
-    | Echo'     -- ^ @\'E\'@ /9th/
-    | Golf'     -- ^ @\'G\'@ /10th/
-    | Hotel'    -- ^ @\'H\'@ /11th/
-    | Juliet'   -- ^ @\'J\'@ /12th/
-    | Kilo'     -- ^ @\'K\'@ /13th/
-    | Lima'     -- ^ @\'L\'@ /14th/
-    | Mike'     -- ^ @\'M\'@ /15th/
-    | November' -- ^ @\'N\'@ /16th/
-    | Papa'     -- ^ @\'P\'@ /17th/
-    | Sierra'   -- ^ @\'S\'@ /18th/
-    | Tango'    -- ^ @\'T\'@ /19th/
-    | Victor'   -- ^ @\'V\'@ /20th/
-    | Whiskey'  -- ^ @\'W\'@ /21st/
-    | XRay'     -- ^ @\'X\'@ /22nd/
-    | Yankee'   -- ^ @\'Y\'@ /23rd/
-    | Zulu'     -- ^ @\'Z\'@ /24th/
+    = -- | @\'0\'@ /0th/
+      Zero'
+    | -- | @\'1\'@ /1st/
+      One'
+    | -- | @\'3\'@ /2nd/
+      Three'
+    | -- | @\'4\'@ /3rd/
+      Four'
+    | -- | @\'7\'@ /4th/
+      Seven'
+    | -- | @\'8\'@ /5th/
+      Eight'
+    | -- | @\'9\'@ /6th/
+      Nine'
+    | -- | @\'A\'@ /7th/
+      Alpha'
+    | -- | @\'C\'@ /8th/
+      Charlie'
+    | -- | @\'E\'@ /9th/
+      Echo'
+    | -- | @\'G\'@ /10th/
+      Golf'
+    | -- | @\'H\'@ /11th/
+      Hotel'
+    | -- | @\'J\'@ /12th/
+      Juliet'
+    | -- | @\'K\'@ /13th/
+      Kilo'
+    | -- | @\'L\'@ /14th/
+      Lima'
+    | -- | @\'M\'@ /15th/
+      Mike'
+    | -- | @\'N\'@ /16th/
+      November'
+    | -- | @\'P\'@ /17th/
+      Papa'
+    | -- | @\'S\'@ /18th/
+      Sierra'
+    | -- | @\'T\'@ /19th/
+      Tango'
+    | -- | @\'V\'@ /20th/
+      Victor'
+    | -- | @\'W\'@ /21st/
+      Whiskey'
+    | -- | @\'X\'@ /22nd/
+      XRay'
+    | -- | @\'Y\'@ /23rd/
+      Yankee'
+    | -- | @\'Z\'@ /24th/
+      Zulu'
     deriving (Eq, Ord, Enum, Bounded)
 
 instance Locator Latin25 where
     locatorToDigit x =
         case x of
-            Zero'   -> '0'
-            One'    -> '1'
-            Three'  -> '3'
-            Four'   -> '4'
-            Seven'  -> '7'
-            Eight'  -> '8'
-            Nine'   -> '9'
-            Alpha'  -> 'A'
+            Zero' -> '0'
+            One' -> '1'
+            Three' -> '3'
+            Four' -> '4'
+            Seven' -> '7'
+            Eight' -> '8'
+            Nine' -> '9'
+            Alpha' -> 'A'
             Charlie' -> 'C'
-            Echo'   -> 'E'
-            Golf'   -> 'G'
-            Hotel'  -> 'H'
+            Echo' -> 'E'
+            Golf' -> 'G'
+            Hotel' -> 'H'
             Juliet' -> 'J'
-            Kilo'   -> 'K'
-            Lima'   -> 'L'
-            Mike'   -> 'M'
+            Kilo' -> 'K'
+            Lima' -> 'L'
+            Mike' -> 'M'
             November' -> 'N'
-            Papa'   -> 'P'
+            Papa' -> 'P'
             Sierra' -> 'S'
-            Tango'  -> 'T'
+            Tango' -> 'T'
             Victor' -> 'V'
-            Whiskey'-> 'W'
-            XRay'   -> 'X'
+            Whiskey' -> 'W'
+            XRay' -> 'X'
             Yankee' -> 'Y'
-            Zulu'   -> 'Z'
+            Zulu' -> 'Z'
 
     digitToLocator :: Char -> Latin25
     digitToLocator c =
@@ -137,8 +150,7 @@
             'X' -> XRay'
             'Y' -> Yankee'
             'Z' -> Zulu'
-            _   -> error "Illegal digit"
-
+            _ -> error "Illegal digit"
 
 instance Show Latin25 where
     show x = [c]
@@ -146,41 +158,43 @@
         c = locatorToDigit x
 
 --
--- | Given a number, convert it to a string in the Latin25 base 25 symbol
--- alphabet. This is useful for primary keys and object identifiers that you
--- need to scan for in log output, for example.
---
+
+{- |
+Given a number, convert it to a string in the Latin25 base 25 symbol
+alphabet. This is useful for primary keys and object identifiers that you
+need to scan for in log output, for example.
+-}
 toLatin25 :: Int -> String
 toLatin25 x =
     showIntAtBase 25 (represent Zulu') x ""
 
 --
+
 -- | Given a number encoded in Locator16, convert it back to an integer.
---
 fromLatin25 :: String -> Int
 fromLatin25 ss =
     foldl (multiply Zulu') 0 ss
 
 --
--- | Take an arbitrary sequence of bytes, hash it with SHA1, then format as a
--- short @limit@-long Latin25 string.
---
--- >>> hashStringToLatin25 5 "You'll get used to it. Or, you'll have a psychotic episode"
--- XSAV1
---
--- 17 characters is the widest hash you can request.
---
+
+{- |
+Take an arbitrary sequence of bytes, hash it with SHA1, then format as a
+short @limit@-long Latin25 string.
+
+>>> hashStringToLatin25 5 "You'll get used to it. Or, you'll have a psychotic episode"
+SG8XP
+
+17 characters is the widest hash you can request.
+-}
 hashStringToLatin25 :: Int -> ByteString -> ByteString
 hashStringToLatin25 limit s'
-  | limit > 17 = error "Can only request a maximum width of 17, sorry"
-  | otherwise  =
-  let
-    s  = S.unpack s'
-    n  = digest s               -- SHA1 hash
-    r  = mod n upperBound       -- trim to specified number of base 25 chars
-    x  = toLatin25 r            -- express in Latin25
-    b' = S.pack (padWithZeros limit x)
-  in
-    b'
+    | limit > 17 = error "Can only request a maximum width of 17, sorry"
+    | otherwise =
+        let s = S.unpack s'
+            n = digest s -- SHA1 hash
+            r = mod n upperBound -- trim to specified number of base 25 chars
+            x = toLatin25 r -- express in Latin25
+            b' = S.pack (padWithZeros limit x)
+         in b'
   where
     upperBound = 25 ^ limit
diff --git a/locators.cabal b/locators.cabal
--- a/locators.cabal
+++ b/locators.cabal
@@ -1,6 +1,6 @@
 cabal-version:       1.24
 name:                locators
-version:             0.3.0.3
+version:             0.3.0.5
 synopsis:            Human exchangable identifiers and locators
 license:             MIT
 license-file:        LICENSE
@@ -13,9 +13,9 @@
 
 author:              Andrew Cowie <istathar@gmail.com>
 maintainer:          Andrew Cowie <istathar@gmail.com>
-copyright:           © 2013-2020 Athae Eredh Siniath and Others
+copyright:           © 2013-2024 Athae Eredh Siniath and Others
 category:            Other
-tested-with:         GHC == 8.8.3
+tested-with:         GHC == 9.6.5
 stability:           experimental
 
 build-type:          Simple
@@ -27,7 +27,7 @@
                      memory,
                      bytestring,
                      containers,
-                     cryptonite
+                     crypton
 
   hs-source-dirs:    lib
   include-dirs:      .
@@ -38,7 +38,6 @@
                      Data.Locator.English16
                      Data.Locator.Latin25
 
-
   ghc-options:       -Wall
                      -Wwarn
                      -fwarn-tabs
@@ -60,7 +59,7 @@
                      QuickCheck,
                      bytestring,
                      containers,
-                     cryptonite,
+                     crypton,
                      locators
 
   hs-source-dirs:    tests
@@ -80,7 +79,7 @@
 
 source-repository    head
   type:              git
-  location:          git@github.com:aesiniath/locators.git
+  location:          git@github.com:aesiniath/locators-haskell.git
 
 
 -- vim: set tabstop=21 expandtab:
diff --git a/tests/TestSuite.hs b/tests/TestSuite.hs
--- a/tests/TestSuite.hs
+++ b/tests/TestSuite.hs
@@ -1,15 +1,5 @@
---
--- Human exchangable identifiers and locators
---
--- Copyright © 2013-2018 Operational Dynamics Consulting, Pty Ltd
---
--- The code in this file, and the program it is a part of, is
--- made available to you by its authors as open source software:
--- you can redistribute it and/or modify it under the terms of
--- the BSD licence.
---
-
 {-# LANGUAGE OverloadedStrings #-}
+
 {-# OPTIONS -fno-warn-unused-imports #-}
 {-# OPTIONS -fno-warn-orphans #-}
 {-# OPTIONS -fno-warn-type-defaults #-}
@@ -18,9 +8,9 @@
 module TestSuite where
 
 import Control.Exception (evaluate)
+import Test.HUnit
 import Test.Hspec
 import Test.Hspec.QuickCheck
-import Test.HUnit
 import Test.QuickCheck (elements, property)
 import Test.QuickCheck.Arbitrary (Arbitrary, arbitrary)
 
@@ -58,18 +48,14 @@
     describe "Hashes" $ do
         testPaddingRefactored
 
-
 testRoundTripEnglish16 =
     prop "safe conversion to/from English16" prop_English16
 
 prop_English16 :: Int -> Bool
 prop_English16 i =
-  let
-    n = abs i
-    decoded = fromEnglish16 (toEnglish16 n)
-  in
-    n == decoded
-
+    let n = abs i
+        decoded = fromEnglish16 (toEnglish16 n)
+     in n == decoded
 
 --
 -- Have to do these manually, since Locator16a is not round-trip safe.
@@ -90,15 +76,15 @@
     it "correctly pads strings" $ do
         padWithZeros 5 "1" `shouldBe` "00001"
         padWithZeros 5 "123456" `shouldBe` "123456"
-        (padWithZeros 11 . toBase62 $ 2^64) `shouldBe` "LygHa16AHYG"
-        (hashStringToBase62 11 . S.pack . show $ 2^64) `shouldBe` "k8SQgkJtxLo"
+        (padWithZeros 11 . toBase62 $ 2 ^ 64) `shouldBe` "LygHa16AHYG"
+        (hashStringToBase62 11 . S.pack . show $ 2 ^ 64) `shouldBe` "k8SQgkJtxLo"
 
 testNegativeNumbers =
     it "doesn't explode if fed a negative number" $ do
         toEnglish16a 1 (-1) `shouldBe` "1"
 
 testKnownLatin25 =
-    it "base 25 is correct" $ do
+    it "base 26 is correct" $ do
         toLatin25 0 `shouldBe` "0"
         toLatin25 1 `shouldBe` "1"
         toLatin25 24 `shouldBe` "Z"
@@ -109,12 +95,10 @@
 
 prop_Latin25 :: Int -> Bool
 prop_Latin25 i =
-  let
-    n = abs i
-    encoded = toLatin25 n
-    decoded = fromLatin25 encoded
-  in
-    n == decoded
+    let n = abs i
+        encoded = toLatin25 n
+        decoded = fromLatin25 encoded
+     in n == decoded
 
 testHashLatin25 =
     it "hashToLatin25 generates an appropriate hash" $ do
