diff --git a/changelog.md b/changelog.md
--- a/changelog.md
+++ b/changelog.md
@@ -1,3 +1,10 @@
+0.2.9
+
+* Remove redundant type-class constraints.
+* Add tests.
+* Add `HasDigit` lens.
+* Add `papa` dependency.
+
 0.2.8
 
 * Add `(/+/)` function.
diff --git a/digit.cabal b/digit.cabal
--- a/digit.cabal
+++ b/digit.cabal
@@ -1,5 +1,5 @@
 name:               digit
-version:            0.2.8
+version:            0.2.9
 license:            BSD3
 license-File:       etc/LICENCE
 author:             Tony Morris <ʇǝu˙sıɹɹoɯʇ@ןןǝʞsɐɥ>
@@ -34,8 +34,8 @@
                     , parsers >= 0.12.3 && < 0.13
                     , semigroups >= 0.12 && < 1.0
                     , template-haskell >= 2.8
-
-                    , parsec
+                    , papa
+                    
   ghc-options:
                     -Wall
 
@@ -62,7 +62,7 @@
                     , directory >= 1.1
                     , QuickCheck >= 2.0
                     , template-haskell >= 2.8
-
+                    , parsec >= 3.1
   ghc-options:
                     -Wall
                     -threaded
diff --git a/src/Data/Digit.hs b/src/Data/Digit.hs
--- a/src/Data/Digit.hs
+++ b/src/Data/Digit.hs
@@ -12,6 +12,8 @@
   Digit
 -- * Destructors
 , foldDigit
+-- * Lenses
+, HasDigit(..)
 -- * Prisms
 , D0(..)
 , x0
@@ -65,30 +67,21 @@
 ) where
 
 import Control.Applicative(many, some)
-import Control.Category((.))
-import Control.Lens(Prism', prism', Iso', iso, Cons(_Cons), Snoc(_Snoc), AsEmpty(_Empty), Each(each), Ixed(ix), Index, IxValue, Plated(plate), Reversing(reversing), (^?), ( # ))
-import Control.Monad(Monad)
-import Data.Char(Char)
 import Data.Data (Data)
-import Data.Eq(Eq((==)))
 import Data.Foldable(foldl', asum)
-import Data.Function(const)
-import Data.Functor((<$), (<$>))
-import Data.Int(Int)
-import Data.List(unfoldr, reverse, notElem, zip, (++))
-import Data.List.NonEmpty(NonEmpty, some1)
-import Data.Maybe(Maybe(Nothing, Just), maybe, fromMaybe)
-import Data.Monoid(Monoid(mempty, mappend))
-import Data.Ord(Ord((<)))
-import Data.Semigroup(Semigroup((<>)))
+import Data.List(unfoldr)
+import Data.List.NonEmpty(some1)
+import Data.Maybe(fromMaybe)
+import Data.Monoid(mappend)
+import Data.Semigroup((<>))
 import Data.String(String)
-import Data.Traversable(traverse)
 import Data.Typeable (Typeable)
 import Language.Haskell.TH(ExpQ, PatQ, varE, varP, mkName)
 import Language.Haskell.TH.Quote(QuasiQuoter(QuasiQuoter), quotePat, quoteExp, quoteDec, dataToExpQ, dataToPatQ, quoteType)
-import Prelude(Show(..), Read(..), Enum(..), Floating((**)), Bounded, Num(..), Integral, Integer, fromIntegral, error, divMod, mod)
+import Prelude(fromEnum, Bounded, error) -- livin on the edge
 import Text.Parser.Char(CharParsing, char, satisfy)
 import Text.Parser.Combinators(skipMany, skipSome, (<?>))
+import Papa
 
 -- $setup
 -- >>> import Prelude
@@ -162,6 +155,14 @@
 foldDigit _  _  _  _  _  _  _  _  _  q9 D9 =
   q9
 
+class HasDigit a where
+  hasdigit ::
+    Lens' a Digit
+
+instance HasDigit Digit where
+  hasdigit =
+    id
+
 class D0 d where
   d0 ::
     Prism'
@@ -643,32 +644,32 @@
   skipSome parsedigit
 
 parsenotdigit ::
-  (Monad p, CharParsing p) =>
+  CharParsing p =>
   p Char
 parsenotdigit =
   let p = satisfy (`notElem` ['0' .. '9'])
   in p <?> "not digit"
 
 parsenotdigits ::
-  (Monad p, CharParsing p) =>
+  CharParsing p =>
   p String
 parsenotdigits =
   many parsenotdigit
 
 parsenotdigits1 ::
-  (Monad p, CharParsing p) =>
+  CharParsing p =>
   p String
 parsenotdigits1 =
   some parsenotdigit
 
 skipnotdigits ::
-  (Monad p, CharParsing p) =>
+  CharParsing p =>
   p ()
 skipnotdigits =
   skipMany parsenotdigit
 
 skipnotdigits1 ::
-  (Monad p, CharParsing p) =>
+  CharParsing p =>
   p ()
 skipnotdigits1 =
   skipSome parsenotdigit
@@ -676,30 +677,6 @@
 instance Show Digit where
   show = show . fromEnum
 
-instance Read Digit where
-  readsPrec _ ('0':t) =
-    [(D0, t)]
-  readsPrec _ ('1':t) =
-    [(D1, t)]
-  readsPrec _ ('2':t) =
-    [(D2, t)]
-  readsPrec _ ('3':t) =
-    [(D3, t)]
-  readsPrec _ ('4':t) =
-    [(D4, t)]
-  readsPrec _ ('5':t) =
-    [(D5, t)]
-  readsPrec _ ('6':t) =
-    [(D6, t)]
-  readsPrec _ ('7':t) =
-    [(D7, t)]
-  readsPrec _ ('8':t) =
-    [(D8, t)]
-  readsPrec _ ('9':t) =
-    [(D9, t)]
-  readsPrec _ _       =
-    []
-
 -- | A QuasiQuoter for any range of @Digit@.
 --
 -- [digitQ|4|] :: Digit
@@ -837,20 +814,49 @@
   let (x, r) = divMod10 (digit # a + digit # b)
   in (mod10 (x :: Integer), r) 
 
+-- |
+--
+--
+-- >>> Digits [x2] .+. Digits [x1, x0]
+-- Digits [1,2]
+--
+-- >>> Digits [x1, x2, x3] .+. Digits [x4, x5, x6]
+-- Digits [5,7,9]
 (.+.) ::
   Digits
   -> Digits
   -> Digits
-Digits d .+. Digits e =
-  Digits (fromMaybe [] ((digitlist # d + (digitlist # e :: Integer)) ^? digitlist))
+d .+. e =
+  fromMaybe mempty ((digits # d + digits # e :: Integer) ^? digits)
 
+-- |
+--
+--
+-- >>> Digits [x2] .*. Digits [x1, x0]
+-- Digits [2,0]
+--
+-- >>> Digits [x1, x2, x3] .*. Digits [x4, x5, x6]
+-- Digits [5,6,0,8,8]
 (.*.) ::
   Digits
   -> Digits
   -> Digits
-Digits d .*. Digits e =
-  Digits (fromMaybe [] ((digitlist # d * (digitlist # e :: Integer)) ^? digitlist))
+d .*. e =
+  fromMaybe mempty ((digits # d * digits # e :: Integer) ^? digits)
 
+-- |
+--
+-- >>> mantissa (Digits []) :: Double
+-- 0.0
+--
+-- > mantissa (Digits [x0]) :: Double
+-- 0.0
+--
+-- >>> mantissa (Digits [x1]) :: Double
+-- 0.1
+--
+-- >>> mantissa (Digits [x1, x9]) :: Double
+-- 0.19
 mantissa ::
   Floating a =>
   Digits
