diff --git a/animate.cabal b/animate.cabal
--- a/animate.cabal
+++ b/animate.cabal
@@ -3,7 +3,7 @@
 -- see: https://github.com/sol/hpack
 
 name:           animate
-version:        0.3.0
+version:        0.4.0
 synopsis:       Animation for sprites
 description:    Prototypical sprite animation with type-safety.
 category:       Game
diff --git a/library/Animate.hs b/library/Animate.hs
--- a/library/Animate.hs
+++ b/library/Animate.hs
@@ -1,10 +1,9 @@
+{-# LANGUAGE DeriveGeneric #-}
 module Animate
-  ( Seconds
-  , DeltaSeconds
-  , Color
+  ( Color
   , FrameIndex
   , Frame(..)
-  , Animations
+  , Animations(..)
   , Loop(..)
   , Position(..)
   , FrameStep(..)
@@ -39,28 +38,23 @@
 import Data.Map (Map)
 import Data.Word (Word8)
 import Data.Text (Text)
-
--- | Avoided newtype wrapper for convenience
-type Seconds = Float
-
--- | Type aliased seconds
-type DeltaSeconds = Seconds
+import GHC.Generics (Generic)
 
 -- | Alias for RGB (8bit, 8bit, 8bit)
 type Color = (Word8, Word8, Word8)
 
 type FrameIndex = Int
 
-data Frame loc = Frame
+data Frame loc delay = Frame
   { fLocation :: loc -- ^ User defined reference to the location of a sprite. For example, a sprite sheet clip.
-  , fDelay :: Seconds -- ^ Minimium amount of time for the frame to last.
-  } deriving (Show, Eq)
+  , fDelay :: delay -- ^ Minimium amount of units for the frame to last.
+  } deriving (Show, Eq, Generic)
 
--- | Type safe animation set. Use an sum type with an `Enum` and `Bounded` instance for the animation, 'a'.
-newtype Animations key loc = Animations { unAnimations :: V.Vector (V.Vector (Frame loc)) }
+-- | Type safe animation set. Use a sum type with an `Enum` and `Bounded` instance for the animation, @a@.
+newtype Animations key loc delay = Animations { unAnimations :: V.Vector (V.Vector (Frame loc delay)) }
   deriving (Show, Eq)
 
--- | Sematically for an animation key constraint
+-- | Semantically for an animation key constraint
 class (Ord key, Bounded key, Enum key) => Key key
 
 -- | Animation Keyframe. `keyName` is used for JSON parsing.
@@ -74,7 +68,7 @@
   , scW :: Int
   , scH :: Int
   , scOffset :: Maybe (Int, Int)
-  } deriving (Show, Eq)
+  } deriving (Show, Eq, Generic)
 
 instance ToJSON SpriteClip where
   toJSON SpriteClip{scX,scY,scW,scH,scOffset} = case scOffset of
@@ -92,21 +86,21 @@
       return SpriteClip { scX = x, scY = y, scW = w, scH = h, scOffset = Just (ofsX, ofsY) })
 
 -- | Generalized sprite sheet data structure
-data SpriteSheet key img = SpriteSheet
-  { ssAnimations :: Animations key SpriteClip
+data SpriteSheet key img delay = SpriteSheet
+  { ssAnimations :: Animations key SpriteClip delay
   , ssImage :: img
-  }
+  } deriving (Generic)
 
 -- | One way to represent sprite sheet information.
--- | JSON loading is included.
-data SpriteSheetInfo = SpriteSheetInfo
+--   JSON loading is included.
+data SpriteSheetInfo delay = SpriteSheetInfo
   { ssiImage :: FilePath
   , ssiAlpha :: Maybe Color
   , ssiClips :: [SpriteClip]
-  , ssiAnimations :: Map Text [(FrameIndex, Seconds)]
-  } deriving (Show, Eq)
+  , ssiAnimations :: Map Text [(FrameIndex, delay)]
+  } deriving (Show, Eq, Generic)
 
-instance ToJSON SpriteSheetInfo where
+instance ToJSON delay => ToJSON (SpriteSheetInfo delay) where
   toJSON SpriteSheetInfo{ssiImage,ssiAlpha,ssiClips,ssiAnimations} = object
     [ "image" .= ssiImage
     , "alpha" .= ssiAlpha
@@ -114,7 +108,7 @@
     , "animations" .= ssiAnimations
     ]
 
-instance FromJSON SpriteSheetInfo where
+instance FromJSON delay => FromJSON (SpriteSheetInfo delay) where
   parseJSON (Object o) = do
     image <- o .: "image"
     alpha <- o .: "alpha"
@@ -124,37 +118,38 @@
   parseJSON _ = mzero
 
 -- | Generate animations given each constructor
-animations :: Key key => (key -> [Frame loc]) -> Animations key loc
+animations :: Key key => (key -> [Frame loc delay]) -> Animations key loc delay
 animations getFrames = Animations $ V.fromList $ map (V.fromList . getFrames) [minBound..maxBound]
 
 -- | Lookup the frames of an animation
-framesByAnimation :: Key key => Animations key loc -> key -> V.Vector (Frame loc)
+framesByAnimation :: Key key => Animations key loc delay -> key -> V.Vector (Frame loc delay)
 framesByAnimation (Animations as) k = as V.! fromEnum k
 
 data Loop
   = Loop'Always -- ^ Never stop looping. Animation can never be completed.
   | Loop'Count Int -- ^ Count down loops to below zero. 0 = no loop. 1 = one loop. 2 = two loops. etc.
-  deriving (Show, Eq)
+  deriving (Show, Eq, Generic)
 
 -- | State for progression through an animation
--- | `example = Position minBound 0 0 Loop'Always`
-data Position key = Position
+--
+-- > example = Position minBound 0 0 Loop'Always
+data Position key delay = Position
   { pKey :: key -- ^ Index for the animation.
   , pFrameIndex :: FrameIndex -- ^ Index wihin the animation. WARNING: Modifying to below zero or equal-to-or-greater-than-the-frame-count will throw out of bounds errors.
-  , pCounter :: Seconds -- ^ Accumulated seconds to end of the frame. Will continue to compound if animation is completed.
+  , pCounter :: delay -- ^ Accumulated units to end of the frame. Will continue to compound if animation is completed.
   , pLoop :: Loop -- ^ How to loop through an animation. Loop'Count is a count down.
-  } deriving (Show, Eq)
+  } deriving (Show, Eq, Generic)
 
 -- | New `Position` with its animation key to loop forever
-initPosition :: Key key => key -> Position key
+initPosition :: (Num delay, Key key) => key -> Position key delay
 initPosition key = initPositionWithLoop key Loop'Always
 
 -- | New `Position` with its animation key with a limited loop
-initPositionLoops :: Key key => key -> Int -> Position key
+initPositionLoops :: (Num delay, Key key) => key -> Int -> Position key delay
 initPositionLoops key count = initPositionWithLoop key (Loop'Count count)
 
 -- | New `Position`
-initPositionWithLoop :: Key key => key -> Loop -> Position key
+initPositionWithLoop :: (Num delay, Key key) => key -> Loop -> Position key delay
 initPositionWithLoop key loop = Position
   { pKey = key
   , pFrameIndex = 0
@@ -163,20 +158,20 @@
   }
 
 -- | You can ignore. An intermediate type for `stepPosition` to judge how to increment the current frame.
-data FrameStep
-  = FrameStep'Counter Seconds -- ^ New counter to compare against the frame's delay.
-  | FrameStep'Delta DeltaSeconds -- ^ How much delta to carry over into the next frame.
-  deriving (Show, Eq)
+data FrameStep delay
+  = FrameStep'Counter delay -- ^ New counter to compare against the frame's delay.
+  | FrameStep'Delta delay -- ^ How much delta to carry over into the next frame.
+  deriving (Show, Eq, Generic)
 
 -- | Intermediate function for how a frame should be step through.
-stepFrame :: Frame loc -> Position key -> DeltaSeconds -> FrameStep
+stepFrame :: (Num delay, Ord delay) => Frame loc delay -> Position key delay -> delay -> FrameStep delay
 stepFrame Frame{fDelay} Position{pCounter} delta =
   if pCounter + delta >= fDelay
     then FrameStep'Delta $ pCounter + delta - fDelay
     else FrameStep'Counter $ pCounter + delta
 
 -- | Step through the animation resulting a new position.
-stepPosition :: Key key => Animations key loc -> Position key -> DeltaSeconds -> Position key
+stepPosition :: (Num delay, Ord delay, Key key) => Animations key loc delay -> Position key delay -> delay -> Position key delay
 stepPosition as p d =
   case frameStep of
     FrameStep'Counter counter -> p{pCounter = counter }
@@ -196,16 +191,16 @@
           , pLoop = Loop'Count n' }
 
 -- | Use the position to find the current frame of the animation.
-currentFrame :: Key key => Animations key loc -> Position key -> Frame loc
+currentFrame :: (Num delay, Key key) => Animations key loc delay -> Position key delay -> Frame loc delay
 currentFrame anis Position{pKey,pFrameIndex} = (framesByAnimation anis pKey) V.! pFrameIndex
 
 -- | Use the position to find the current location, lik a sprite sheet clip, of the animation.
-currentLocation :: Key key => Animations key loc -> Position key -> loc
+currentLocation :: (Num delay, Key key) => Animations key loc delay -> Position key delay -> loc
 currentLocation anis p = fLocation (currentFrame anis p)
 
 -- | The animation has finished all its frames. Useful for signalling into switching to another animation.
 --   With a Loop'Always, the animation will never be completed.
-isAnimationComplete :: Key key => Animations key loc -> Position key -> Bool
+isAnimationComplete :: (Key key, Num delay, Ord delay) => Animations key loc delay -> Position key delay -> Bool
 isAnimationComplete as p = case pLoop p of
   Loop'Always -> False
   Loop'Count n -> n < 0 && pFrameIndex p == lastIndex && pCounter p >= fDelay lastFrame
@@ -214,41 +209,42 @@
     lastIndex = V.length frames - 1
     lastFrame = frames V.! lastIndex
 
--- | Cycle through the next animation key
+-- | Cycle through the next animation key.
 nextKey :: Key key => key -> key
 nextKey key = if key == maxBound then minBound else succ key
 
--- | Cycle through the previous animation key
+-- | Cycle through the previous animation key.
 prevKey :: Key key => key -> key
 prevKey key = if key == minBound then maxBound else pred key
 
--- | Simple function diff'ing the position for loop change
+-- | Simple function diff'ing the position for loop change.
 positionHasLooped
-  :: Position key -- ^ Previous
-  -> Position key -- ^ Next
+  :: Position key delay -- ^ Previous
+  -> Position key delay -- ^ Next
   -> Bool
 positionHasLooped Position{ pLoop = Loop'Count c } Position{ pLoop = Loop'Count c' } = c > c'
 positionHasLooped Position{ pLoop = Loop'Always } _ = False
 positionHasLooped _ Position{ pLoop = Loop'Always } = False
 
 -- | Quick function for loading `SpriteSheetInfo`.
--- | Check the example.
+--   Check the example.
 readSpriteSheetInfoJSON
-  :: FilePath -- ^ Path of the sprite sheet info JSON file
-  -> IO SpriteSheetInfo
+  :: FromJSON delay
+  => FilePath -- ^ Path of the sprite sheet info JSON file
+  -> IO (SpriteSheetInfo delay)
 readSpriteSheetInfoJSON path = do
   metaBytes <- BL.readFile path
   case eitherDecode metaBytes of
     Left _err -> error $ "Cannot parse Sprite Sheet Info \"" ++ path ++ "\""
     Right ssi -> return ssi
 
--- | Quick function for loading `SpriteSheetInfo`, then using it to load its image for a `SpriteSheet`
--- | Check the example.
+-- | Quick function for loading `SpriteSheetInfo`, then using it to load its image for a `SpriteSheet`.
+--   Check the example.
 readSpriteSheetJSON
-  :: KeyName key
-  => (FilePath -> Maybe Color -> IO img) -- ^ Inject animage loading function
+  :: (KeyName key, FromJSON delay)
+  => (FilePath -> Maybe Color -> IO img) -- ^ Inject an image loading function
   -> FilePath -- ^ Path of the sprite sheet info JSON file
-  -> IO (SpriteSheet key img)
+  -> IO (SpriteSheet key img delay)
 readSpriteSheetJSON loadImage infoPath = do
   SpriteSheetInfo{ssiImage, ssiClips, ssiAnimations, ssiAlpha} <- readSpriteSheetInfoJSON infoPath
   i <- loadImage ssiImage ssiAlpha
diff --git a/package.yaml b/package.yaml
--- a/package.yaml
+++ b/package.yaml
@@ -1,5 +1,5 @@
 name: animate
-version: '0.3.0'
+version: '0.4.0'
 category: Game
 synopsis: Animation for sprites
 description: Prototypical sprite animation with type-safety.
