diff --git a/finite-typelits.cabal b/finite-typelits.cabal
--- a/finite-typelits.cabal
+++ b/finite-typelits.cabal
@@ -1,5 +1,5 @@
 name:                finite-typelits
-version:             0.1.0.0
+version:             0.1.1.0
 synopsis:            A type inhabited by finitely many values, indexed by type-level naturals.
 description:         A type inhabited by finitely many values, indexed by type-level naturals.
 homepage:            https://github.com/mniip/finite-typelits
@@ -14,5 +14,6 @@
 library
   exposed-modules:     Data.Finite, Data.Finite.Internal
   build-depends:       base == 4.*
+                     , deepseq >= 1.4
   hs-source-dirs:      src
   default-language:    Haskell2010
diff --git a/src/Data/Finite.hs b/src/Data/Finite.hs
--- a/src/Data/Finite.hs
+++ b/src/Data/Finite.hs
@@ -27,10 +27,9 @@
     where
 
 import Data.Maybe
-import Data.Ratio
 import GHC.TypeLits
 
-import Data.Finite.Internal (Finite(Finite))
+import Data.Finite.Internal
 
 -- | Convert an 'Integer' into a 'Finite', returning 'Nothing' if the input is out of bounds.
 packFinite :: KnownNat n => Integer -> Maybe (Finite n)
@@ -44,78 +43,18 @@
 packFiniteProxy :: KnownNat n => proxy n -> Integer -> Maybe (Finite n)
 packFiniteProxy _ = packFinite
 
--- | Convert an 'Integer' into a 'Finite', throwing an error if the input is out of bounds.
-finite :: KnownNat n => Integer -> Finite n
-finite x = result
-    where
-        result = if x < natVal result && x >= 0
-            then Finite x
-            else error $ "finite: Integer " ++ show x ++ " is not representable in Finite " ++ show (natVal result)
-
 -- | Same as 'finite' but with a proxy argument to avoid type signatures.
 finiteProxy :: KnownNat n => proxy n -> Integer -> Finite n
 finiteProxy _ = finite
 
--- | Convert a 'Finite' into the corresponding 'Integer'.
-getFinite :: Finite n -> Integer
-getFinite (Finite x) = x
-
-instance Eq (Finite n) where
-    Finite x == Finite y = x == y
-
 -- | Test two different types of finite numbers for equality.
 equals :: Finite n -> Finite m -> Bool
 equals (Finite x) (Finite y) = x == y
 infix 4 `equals`
 
-instance Ord (Finite n) where
-    Finite x `compare` Finite y = x `compare` y
-
 -- | Compare two different types of finite numbers.
 cmp :: Finite n -> Finite m -> Ordering
 cmp (Finite x) (Finite y) = x `compare` y
-
--- | Throws an error for @'Finite' 0@
-instance KnownNat n => Bounded (Finite n) where
-    maxBound = result
-        where
-            result = if natVal result > 0
-                then Finite $ natVal result - 1
-                else error "maxBound: Finite 0 is uninhabited"
-    minBound = result
-        where
-            result = if natVal result > 0
-                then Finite 0
-                else error "minBound: Finite 0 is uninhabited"
-
-instance KnownNat n => Enum (Finite n) where
-    fromEnum = fromEnum . getFinite
-    toEnum = finite . toEnum
-    enumFrom x = enumFromTo x maxBound
-    enumFromThen x y = enumFromThenTo x y (if x >= y then minBound else maxBound)
-
-instance Show (Finite n) where
-    showsPrec d (Finite x) = showParen (d > 9) $ showString "finite " . showsPrec 10 x
-
--- | Modulo arithmetic. Only the 'fromInteger' function is supposed to be useful.
-instance KnownNat n => Num (Finite n) where
-    fx@(Finite x) + Finite y = Finite $ (x + y) `mod` natVal fx
-    fx@(Finite x) - Finite y = Finite $ (x - y) `mod` natVal fx
-    fx@(Finite x) * Finite y = Finite $ (x * y) `mod` natVal fx
-    abs fx = fx
-    signum _ = fromInteger 1
-    fromInteger x = result
-        where
-            result = if x < natVal result && x >= 0
-                then Finite x
-                else error $ "fromInteger: Integer " ++ show x ++ " is not representable in Finite " ++ show (natVal result)
-
-instance KnownNat n => Real (Finite n) where
-    toRational (Finite x) = x % 1
-
-instance KnownNat n => Integral (Finite n) where
-    quotRem (Finite x) (Finite y) = (Finite $ x `quot` y, Finite $ x `rem` y)
-    toInteger (Finite x) = x
 
 -- | Convert a type-level literal into a 'Finite'.
 natToFinite :: (KnownNat n, KnownNat m, n + 1 <= m) => proxy n -> Finite m
diff --git a/src/Data/Finite/Internal.hs b/src/Data/Finite/Internal.hs
--- a/src/Data/Finite/Internal.hs
+++ b/src/Data/Finite/Internal.hs
@@ -7,17 +7,79 @@
 -- Stability   :  experimental
 -- Portability :  portable
 --------------------------------------------------------------------------------
-{-# LANGUAGE KindSignatures, DataKinds #-}
+{-# LANGUAGE KindSignatures, DataKinds, DeriveGeneric #-}
 module Data.Finite.Internal
     (
-        Finite(Finite)
+        Finite(Finite),
+        finite,
+        getFinite
     )
     where
 
 import GHC.TypeLits
+import GHC.Generics
+import Control.DeepSeq
+import Data.Ratio
 
 -- | Finite number type. @'Finite' n@ is inhabited by exactly @n@ values. Invariants:
 --
 -- prop> getFinite x < natVal x
 -- prop> getFinite x >= 0
 newtype Finite (n :: Nat) = Finite Integer
+                          deriving (Eq, Ord, Generic)
+
+-- | Convert an 'Integer' into a 'Finite', throwing an error if the input is out of bounds.
+finite :: KnownNat n => Integer -> Finite n
+finite x = result
+    where
+        result = if x < natVal result && x >= 0
+            then Finite x
+            else error $ "finite: Integer " ++ show x ++ " is not representable in Finite " ++ show (natVal result)
+
+-- | Convert a 'Finite' into the corresponding 'Integer'.
+getFinite :: Finite n -> Integer
+getFinite (Finite x) = x
+
+-- | Throws an error for @'Finite' 0@
+instance KnownNat n => Bounded (Finite n) where
+    maxBound = result
+        where
+            result = if natVal result > 0
+                then Finite $ natVal result - 1
+                else error "maxBound: Finite 0 is uninhabited"
+    minBound = result
+        where
+            result = if natVal result > 0
+                then Finite 0
+                else error "minBound: Finite 0 is uninhabited"
+
+instance KnownNat n => Enum (Finite n) where
+    fromEnum = fromEnum . getFinite
+    toEnum = finite . toEnum
+    enumFrom x = enumFromTo x maxBound
+    enumFromThen x y = enumFromThenTo x y (if x >= y then minBound else maxBound)
+
+instance Show (Finite n) where
+    showsPrec d (Finite x) = showParen (d > 9) $ showString "finite " . showsPrec 10 x
+
+-- | Modulo arithmetic. Only the 'fromInteger' function is supposed to be useful.
+instance KnownNat n => Num (Finite n) where
+    fx@(Finite x) + Finite y = Finite $ (x + y) `mod` natVal fx
+    fx@(Finite x) - Finite y = Finite $ (x - y) `mod` natVal fx
+    fx@(Finite x) * Finite y = Finite $ (x * y) `mod` natVal fx
+    abs fx = fx
+    signum _ = fromInteger 1
+    fromInteger x = result
+        where
+            result = if x < natVal result && x >= 0
+                then Finite x
+                else error $ "fromInteger: Integer " ++ show x ++ " is not representable in Finite " ++ show (natVal result)
+
+instance KnownNat n => Real (Finite n) where
+    toRational (Finite x) = x % 1
+
+instance KnownNat n => Integral (Finite n) where
+    quotRem (Finite x) (Finite y) = (Finite $ x `quot` y, Finite $ x `rem` y)
+    toInteger (Finite x) = x
+
+instance NFData (Finite n)
