diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -1,20 +1,20 @@
-Copyright (c) 2014 Cerek Hillen
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be included
-in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+Copyright (c) 2014 Cerek Hillen
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/Setup.hs b/Setup.hs
--- a/Setup.hs
+++ b/Setup.hs
@@ -1,2 +1,2 @@
-import Distribution.Simple
-main = defaultMain
+import Distribution.Simple
+main = defaultMain
diff --git a/spice.cabal b/spice.cabal
--- a/spice.cabal
+++ b/spice.cabal
@@ -1,51 +1,55 @@
-name:                spice
-version:             0.3.3.2
-synopsis:            An FRP-based game engine written in Haskell.
-description:         An FRP-based game engine written in Haskell. - See the homepage for more information.
-homepage:            http://github.com/crockeo/spice
-license:             MIT
-license-file:        LICENSE
-author:              Cerek Hillen
-maintainer:          Cerek Hillen <cerekh@gmail.com>
-copyright:           (c) 2014, Cerek Hillen
-category:            FRP
-build-type:          Simple
-cabal-version:       >=1.10
-
-library
-  ghc-options:         -Wall -fno-warn-unused-do-bind
-
-  exposed-modules:     FRP.Spice
-                       FRP.Spice.Graphics
-                       FRP.Spice.Math
-
-  other-modules:       FRP.Spice.Config
-                       FRP.Spice.Engine
-                       FRP.Spice.Engine.Driver
-                       FRP.Spice.Engine.Network
-                       FRP.Spice.Engine.RenderWrapper
-                       FRP.Spice.Engine.RunInput
-                       FRP.Spice.Game
-                       FRP.Spice.Graphics.Color
-                       FRP.Spice.Graphics.Element
-                       FRP.Spice.Graphics.Geometry
-                       FRP.Spice.Graphics.Scene
-                       FRP.Spice.Graphics.Utils
-                       FRP.Spice.Input
-                       FRP.Spice.Input.Backend
-                       FRP.Spice.Input.Keyboard
-                       FRP.Spice.Input.Mouse
-                       FRP.Spice.Input.MousePosition
-                       FRP.Spice.Math.Vector
-                       FRP.Spice.Utils.DoList
-
-  hs-source-dirs:      src/
-
-  build-depends:       base         == 4.7.*
-               ,       elerea       == 2.7.*
-               ,       GLFW         == 0.5.*
-               ,       containers   == 0.5.*
-               ,       data-default == 0.5.*
-               ,       OpenGL
-
-  default-language:    Haskell2010
+name:                spice
+version:             0.4.0.0
+synopsis:            An FRP-based game engine written in Haskell.
+description:         An FRP-based game engine written in Haskell. - See the homepage for more information.
+homepage:            http://github.com/crockeo/spice
+license:             MIT
+license-file:        LICENSE
+author:              Cerek Hillen
+maintainer:          Cerek Hillen <cerekh@gmail.com>
+copyright:           (c) 2014, Cerek Hillen
+category:            FRP
+build-type:          Simple
+cabal-version:       >=1.10
+
+library
+  ghc-options:         -Wall -fno-warn-unused-do-bind
+
+  exposed-modules:     FRP.Spice
+                       FRP.Spice.Graphics
+                       FRP.Spice.Math
+
+  other-modules:       FRP.Spice.Assets
+                       FRP.Spice.Config
+                       FRP.Spice.Engine
+                       FRP.Spice.Engine.Driver
+                       FRP.Spice.Engine.Network
+                       FRP.Spice.Engine.RenderWrapper
+                       FRP.Spice.Engine.RunInput
+                       FRP.Spice.Game
+                       FRP.Spice.Graphics.Color
+                       FRP.Spice.Graphics.Geometry
+                       FRP.Spice.Graphics.Scene
+                       FRP.Spice.Graphics.Sprite
+                       FRP.Spice.Graphics.Utils
+                       FRP.Spice.Input
+                       FRP.Spice.Input.Backend
+                       FRP.Spice.Input.Keyboard
+                       FRP.Spice.Input.Mouse
+                       FRP.Spice.Input.MousePosition
+                       FRP.Spice.Math.Vector
+                       FRP.Spice.Utils.DoList
+
+  hs-source-dirs:      src/
+
+  build-depends:       base              == 4.7.*
+               ,       elerea            == 2.7.*
+               ,       GLFW              == 0.5.*
+               ,       containers        == 0.5.*
+               ,       data-default      == 0.5.*
+               ,       bytestring        == 0.10.*
+               ,       JuicyPixels       == 3.1.*
+               ,       JuicyPixels-repa  == 0.7.*
+               ,       OpenGL
+
+  default-language:    Haskell2010
diff --git a/src/FRP/Spice.hs b/src/FRP/Spice.hs
--- a/src/FRP/Spice.hs
+++ b/src/FRP/Spice.hs
@@ -1,22 +1,24 @@
-{-|
-  This module re-exports some other modules in the spice library so that you
-  needn't import all of them explicitly.
--}
-module FRP.Spice ( module Graphics.UI.GLFW
-                 , module Data.Map.Strict
-
-                 , module FRP.Spice.Config
-                 , module FRP.Spice.Engine
-                 , module FRP.Spice.Input
-                 , module FRP.Spice.Game
-                 ) where
-
------------------------
--- Rexported Imports --
-import Graphics.UI.GLFW (Key (..), SpecialKey (..), MouseButton (..))
-import Data.Map.Strict ((!))
-
-import FRP.Spice.Config
-import FRP.Spice.Engine
-import FRP.Spice.Input
-import FRP.Spice.Game
+{-|
+  This module re-exports some other modules in the spice library so that you
+  needn't import all of them explicitly.
+-}
+module FRP.Spice ( module Graphics.UI.GLFW
+                 , module Data.Map.Strict
+
+                 , module FRP.Spice.Assets
+                 , module FRP.Spice.Config
+                 , module FRP.Spice.Engine
+                 , module FRP.Spice.Input
+                 , module FRP.Spice.Game
+                 ) where
+
+-----------------------
+-- Rexported Imports --
+import Graphics.UI.GLFW (Key (..), SpecialKey (..), MouseButton (..))
+import Data.Map.Strict ((!))
+
+import FRP.Spice.Assets
+import FRP.Spice.Config
+import FRP.Spice.Engine
+import FRP.Spice.Input
+import FRP.Spice.Game
diff --git a/src/FRP/Spice/Assets.hs b/src/FRP/Spice/Assets.hs
new file mode 100644
--- /dev/null
+++ b/src/FRP/Spice/Assets.hs
@@ -0,0 +1,71 @@
+{-|
+  This module provides a clean way to load assets that will later be used in
+  the spice-based program.
+-}
+module FRP.Spice.Assets where
+
+--------------------
+-- Global Imports --
+import qualified Data.Map.Strict as Map
+import Control.Monad
+import Data.Default
+
+-------------------
+-- Local Imports --
+import FRP.Spice.Graphics.Sprite
+import FRP.Spice.Utils.DoList
+
+----------
+-- Code --
+
+{-|
+  A single call to load an asset.
+-}
+data LoadAsset = LoadSprite FilePath
+
+{-|
+  A list of @'LoadAssets'@ that may be composed in do-notation.
+-}
+type LoadAssets = DoList [LoadAsset]
+
+{-|
+  The data structure that contains the loaded assets.
+-}
+data Assets = Assets { sprites :: Map.Map FilePath Sprite }
+
+{-|
+  The default state for the @'Assets'@ data type. Used as the initial state for
+  @'performAssetLoads'@.
+-}
+defaultAssets :: Assets
+defaultAssets =
+  Assets { sprites = Map.fromList [] }
+
+{-|
+  A synonym for @'defaultAssets'@ to fit within the data-default library.
+-}
+instance Default Assets where
+  def = defaultAssets
+
+{-|
+  Appending a @'Sprite'@ to an @'Assets'@.
+-}
+appendSprite :: Assets -> FilePath -> Sprite -> Assets
+appendSprite assets path sprite =
+  assets { sprites = Map.insert path sprite $ sprites assets }
+
+{-|
+  Performing the actual loading upon a @'LoadAssets'@.
+-}
+performAssetLoads :: LoadAssets -> IO Assets
+performAssetLoads la =
+  performAssetLoads' (values la) defaultAssets
+  where performAssetLoads' :: [LoadAsset] -> Assets -> IO Assets
+        performAssetLoads' []                   assets = return assets
+        performAssetLoads' (LoadSprite path:xs) assets = (liftM (appendSprite assets path) $ loadSprite path) >>= performAssetLoads' xs
+
+{-|
+  Loading a @'Sprite'@ asset.
+-}
+loadSpriteAsset :: FilePath -> LoadAssets
+loadSpriteAsset = fromValues . return . LoadSprite
diff --git a/src/FRP/Spice/Config.hs b/src/FRP/Spice/Config.hs
--- a/src/FRP/Spice/Config.hs
+++ b/src/FRP/Spice/Config.hs
@@ -1,44 +1,44 @@
-{-|
-  This module handles the configuration for the project.
--}
-module FRP.Spice.Config where
-
---------------------
--- Global Imports --
-import Data.Default
-
-----------
--- Code --
-
-{-|
-  A datatype to configure the window settings when creating an OpenGL context
-  using @'FRP.Spice.Engine.startEngine'@ in the engine.
--}
-data WindowConfig = WindowConfig { getWindowWidth      :: Int
-                                 , getWindowHeight     :: Int
-                                 , getWindowFullscreen :: Bool
-                                 , getWindowTitle      :: String
-                                 }
-  deriving (Eq, Show, Read)
-
-{-|
-  The default for @'WindowConfig'@
-
-  > getWindowWidth      = 640
-  > getWindowHeight     = 480
-  > getWindowFullscreen = False
-  > getWindowTitle      = "Spice Application"
--}
-defaultWindowConfig :: WindowConfig
-defaultWindowConfig = WindowConfig { getWindowWidth      = 640
-                                   , getWindowHeight     = 480
-                                   , getWindowFullscreen = False
-                                   , getWindowTitle      = "Spice Application"
-                                   }
-
-{-|
-  A default instance for @'WindowConfig'@. Equivalent to calling
-  @'defaultWindowConfig'@.
--}
-instance Default WindowConfig where
-  def = defaultWindowConfig
+{-|
+  This module handles the configuration for the project.
+-}
+module FRP.Spice.Config where
+
+--------------------
+-- Global Imports --
+import Data.Default
+
+----------
+-- Code --
+
+{-|
+  A datatype to configure the window settings when creating an OpenGL context
+  using @'FRP.Spice.Engine.startEngine'@ in the engine.
+-}
+data WindowConfig = WindowConfig { getWindowWidth      :: Int
+                                 , getWindowHeight     :: Int
+                                 , getWindowFullscreen :: Bool
+                                 , getWindowTitle      :: String
+                                 }
+  deriving (Eq, Show, Read)
+
+{-|
+  The default for @'WindowConfig'@
+
+  > getWindowWidth      = 640
+  > getWindowHeight     = 480
+  > getWindowFullscreen = False
+  > getWindowTitle      = "Spice Application"
+-}
+defaultWindowConfig :: WindowConfig
+defaultWindowConfig = WindowConfig { getWindowWidth      = 640
+                                   , getWindowHeight     = 480
+                                   , getWindowFullscreen = False
+                                   , getWindowTitle      = "Spice Application"
+                                   }
+
+{-|
+  A default instance for @'WindowConfig'@. Equivalent to calling
+  @'defaultWindowConfig'@.
+-}
+instance Default WindowConfig where
+  def = defaultWindowConfig
diff --git a/src/FRP/Spice/Engine.hs b/src/FRP/Spice/Engine.hs
--- a/src/FRP/Spice/Engine.hs
+++ b/src/FRP/Spice/Engine.hs
@@ -1,86 +1,90 @@
-{-|
-  This module handles starting the engine. This is done via the use of the
-  @'startEngine'@ function.
--}
-module FRP.Spice.Engine (startEngine) where
-
---------------------
--- Global Imports --
-import Graphics.Rendering.OpenGL
-import Graphics.UI.GLFW as GLFW
-import Data.IORef
-
--------------------
--- Local Imports --
-import FRP.Spice.Engine.RunInput
-import FRP.Spice.Engine.Network
-import FRP.Spice.Engine.Driver
-import FRP.Spice.Input.Backend
-import FRP.Spice.Config
-import FRP.Spice.Game
-import FRP.Spice.Math
-
-----------
--- Code --
-
--- Making the size from a WindowConfig
-makeSize :: WindowConfig -> Size
-makeSize wc = Size (fromIntegral $ getWindowWidth wc) (fromIntegral $ getWindowHeight wc)
-
--- Making the displaybits from a WindowConfig
-makeDisplayBits :: [DisplayBits]
-makeDisplayBits = [DisplayRGBBits 8 8 8, DisplayAlphaBits 8, DisplayDepthBits 24]
-
--- Making the window mode from a WindowConfig
-makeWindowMode :: WindowConfig -> WindowMode
-makeWindowMode wc =
-  if getWindowFullscreen wc
-    then FullScreen
-    else Window
-
--- Resizing the window
-resizeCallback :: IORef (Vector Int) -> WindowSizeCallback
-resizeCallback wSize size@(Size w h) = do
-  writeIORef wSize $ Vector (fromIntegral w) (fromIntegral h)
-  viewport $= (Position 0 0, size)
-
-{-|
-  Starting the spice engine with the parameters prescribed in the
-  @'WindowConfig'@. It updates and renders the @'Game'@ automatically so all
-  you need to to is set up the @'WindowConfig'@ and make a datatype with an
-  instance of @'Game'@.
--}
-startEngine :: Game a => WindowConfig -> a -> IO ()
-startEngine wc game = do
-  -- Opening the window
-  initialize
-  openWindow (makeSize wc) makeDisplayBits (makeWindowMode wc)
-  windowTitle $= getWindowTitle wc
-
-  -- Checking for the window being closed
-  closed <- newIORef False
-  windowCloseCallback $= do
-    writeIORef closed True
-    return True
-
-  -- Function to run on window resize
-  wSizeRef <- newIORef $ Vector (getWindowWidth wc) (getWindowHeight wc)
-  windowSizeCallback $= resizeCallback wSizeRef
-
-  -- Getting the input container
-  ic <- makeInputContainer
-
-  -- Updating the input
-  mousePosCallback    $= makeMousePositionCallback ic wSizeRef
-  keyCallback         $= makeKeyboardCallback ic
-  mouseButtonCallback $= makeMouseCallback ic
-
-  -- Creating the network
-  network <- makeNetwork (getInput ic) game
-
-  -- Driving the network
-  GLFW.time $= 0
-  driveNetwork network $ runInput closed
-
-  -- Closing the window, after all is said and done
-  closeWindow
+{-|
+  This module handles starting the engine. This is done via the use of the
+  @'startEngine'@ function.
+-}
+module FRP.Spice.Engine (startEngine) where
+
+--------------------
+-- Global Imports --
+import Graphics.Rendering.OpenGL
+import Graphics.UI.GLFW as GLFW
+import Data.IORef
+
+-------------------
+-- Local Imports --
+import FRP.Spice.Engine.RunInput
+import FRP.Spice.Engine.Network
+import FRP.Spice.Engine.Driver
+import FRP.Spice.Input.Backend
+import FRP.Spice.Assets
+import FRP.Spice.Config
+import FRP.Spice.Game
+import FRP.Spice.Math
+
+----------
+-- Code --
+
+-- Making the size from a WindowConfig
+makeSize :: WindowConfig -> Size
+makeSize wc = Size (fromIntegral $ getWindowWidth wc) (fromIntegral $ getWindowHeight wc)
+
+-- Making the displaybits from a WindowConfig
+makeDisplayBits :: [DisplayBits]
+makeDisplayBits = [DisplayRGBBits 8 8 8, DisplayAlphaBits 8, DisplayDepthBits 24]
+
+-- Making the window mode from a WindowConfig
+makeWindowMode :: WindowConfig -> WindowMode
+makeWindowMode wc =
+  if getWindowFullscreen wc
+    then FullScreen
+    else Window
+
+-- Resizing the window
+resizeCallback :: IORef (Vector Int) -> WindowSizeCallback
+resizeCallback wSize size@(Size w h) = do
+  writeIORef wSize $ Vector (fromIntegral w) (fromIntegral h)
+  viewport $= (Position 0 0, size)
+
+{-|
+  Starting the spice engine with the parameters prescribed in the
+  @'WindowConfig'@. It updates and renders the @'Game'@ automatically so all
+  you need to to is set up the @'WindowConfig'@ and make a datatype with an
+  instance of @'Game'@.
+-}
+startEngine :: Game a => WindowConfig -> a -> IO ()
+startEngine wc game = do
+  -- Opening the window
+  initialize
+  openWindow (makeSize wc) makeDisplayBits (makeWindowMode wc)
+  windowTitle $= getWindowTitle wc
+
+  -- Checking for the window being closed
+  closed <- newIORef False
+  windowCloseCallback $= do
+    writeIORef closed True
+    return True
+
+  -- Function to run on window resize
+  wSizeRef <- newIORef $ Vector (getWindowWidth wc) (getWindowHeight wc)
+  windowSizeCallback $= resizeCallback wSizeRef
+
+  -- Loading the assets
+  assets <- performAssetLoads $ loadAssets game
+
+  -- Getting the input container
+  ic <- makeInputContainer
+
+  -- Updating the input
+  mousePosCallback    $= makeMousePositionCallback ic wSizeRef
+  keyCallback         $= makeKeyboardCallback ic
+  mouseButtonCallback $= makeMouseCallback ic
+
+  -- Creating the network
+  network <- makeNetwork (getInput ic) game
+
+  -- Driving the network
+  GLFW.time $= 0
+  driveNetwork assets network $ runInput closed
+
+  -- Closing the window, after all is said and done
+  closeWindow
diff --git a/src/FRP/Spice/Engine/Driver.hs b/src/FRP/Spice/Engine/Driver.hs
--- a/src/FRP/Spice/Engine/Driver.hs
+++ b/src/FRP/Spice/Engine/Driver.hs
@@ -1,26 +1,27 @@
-{-|
-  This module need not be used directly. Refer to @'FRP.Spice.Engine'@ instead.
--}
-module FRP.Spice.Engine.Driver where
-
---------------------
--- Global Imports --
-import FRP.Spice.Engine.RenderWrapper
-import FRP.Spice.Game
-
-----------
--- Code --
-
-{-|
-  Driving a network created with the @'FRP.Spice.Engine.Network.makeNetwork'@
-  function and a function such as @'FRP.Spice.Engine.RunInput.runInput'@.
--}
-driveNetwork :: Game a => (Float -> IO a) -> IO (Maybe Float) -> IO ()
-driveNetwork network iomdriver = do
-  mdriver <- iomdriver
-
-  case mdriver of
-    Just driver -> do state <- network driver
-                      renderWrapper $ render state
-                      driveNetwork network iomdriver
-    Nothing     -> return ()
+{-|
+  This module need not be used directly. Refer to @'FRP.Spice.Engine'@ instead.
+-}
+module FRP.Spice.Engine.Driver where
+
+--------------------
+-- Global Imports --
+import FRP.Spice.Engine.RenderWrapper
+import FRP.Spice.Assets
+import FRP.Spice.Game
+
+----------
+-- Code --
+
+{-|
+  Driving a network created with the @'FRP.Spice.Engine.Network.makeNetwork'@
+  function and a function such as @'FRP.Spice.Engine.RunInput.runInput'@.
+-}
+driveNetwork :: Game a => Assets -> (Float -> IO a) -> IO (Maybe Float) -> IO ()
+driveNetwork assets network iomdriver = do
+  mdriver <- iomdriver
+
+  case mdriver of
+    Just driver -> do state <- network driver
+                      renderWrapper $ render assets state
+                      driveNetwork assets network iomdriver
+    Nothing     -> return ()
diff --git a/src/FRP/Spice/Engine/Network.hs b/src/FRP/Spice/Engine/Network.hs
--- a/src/FRP/Spice/Engine/Network.hs
+++ b/src/FRP/Spice/Engine/Network.hs
@@ -1,31 +1,31 @@
-{-|
-  This module need not be used directly. Refer to
-  @'FRP.Spice.Engine.startEngine'@ instead.
--}
-module FRP.Spice.Engine.Network where
-
---------------------
--- Global Imports --
-import FRP.Elerea.Param
-
--------------------
--- Local Imports --
-import FRP.Spice.Input
-import FRP.Spice.Game
-
-----------
--- Code --
-
-{-|
-  The raw update function that @'makeNetwork'@ calls.
--}
-updateFn :: Game a => Float -> Input -> a -> a
-updateFn = update
-
-{-|
-  Creating a network to be used with the
-  @'FRP.Spice.Engine.Driver.driveNetwork'@ function.
--}
-makeNetwork :: Game a => Signal Input -> a -> IO (Float -> IO a)
-makeNetwork inputSignal game =
-  start $ transfer game updateFn inputSignal
+{-|
+  This module need not be used directly. Refer to
+  @'FRP.Spice.Engine.startEngine'@ instead.
+-}
+module FRP.Spice.Engine.Network where
+
+--------------------
+-- Global Imports --
+import FRP.Elerea.Param
+
+-------------------
+-- Local Imports --
+import FRP.Spice.Input
+import FRP.Spice.Game
+
+----------
+-- Code --
+
+{-|
+  The raw update function that @'makeNetwork'@ calls.
+-}
+updateFn :: Game a => Float -> Input -> a -> a
+updateFn = update
+
+{-|
+  Creating a network to be used with the
+  @'FRP.Spice.Engine.Driver.driveNetwork'@ function.
+-}
+makeNetwork :: Game a => Signal Input -> a -> IO (Float -> IO a)
+makeNetwork inputSignal game =
+  start $ transfer game updateFn inputSignal
diff --git a/src/FRP/Spice/Engine/RenderWrapper.hs b/src/FRP/Spice/Engine/RenderWrapper.hs
--- a/src/FRP/Spice/Engine/RenderWrapper.hs
+++ b/src/FRP/Spice/Engine/RenderWrapper.hs
@@ -1,31 +1,31 @@
-{-|
-  This module provides a wrapper to use with a given @'FRP.Spice.Game.Game'@'s
-  render function.
--}
-module FRP.Spice.Engine.RenderWrapper where
-
---------------------
--- Global Imports --
-import Graphics.Rendering.OpenGL
-import Graphics.UI.GLFW
-
---------------------
--- Global Imports --
-import FRP.Spice.Graphics.Scene
-
-----------
--- Code --
-
-{-|
-  A function to be ran on a @'FRP.Spice.Game.Game'@'s render function to
-  provide a bit of a framework around it. It runs @'clear'@ before the render
-  function, and @'flush'@ / @'swapBuffers'@ afterwards.
--}
-renderWrapper :: Scene -> IO ()
-renderWrapper scene = do
-  clear [ColorBuffer]
-
-  renderScene scene
-
-  flush
-  swapBuffers
+{-|
+  This module provides a wrapper to use with a given @'FRP.Spice.Game.Game'@'s
+  render function.
+-}
+module FRP.Spice.Engine.RenderWrapper where
+
+--------------------
+-- Global Imports --
+import Graphics.Rendering.OpenGL
+import Graphics.UI.GLFW
+
+--------------------
+-- Global Imports --
+import FRP.Spice.Graphics.Scene
+
+----------
+-- Code --
+
+{-|
+  A function to be ran on a @'FRP.Spice.Game.Game'@'s render function to
+  provide a bit of a framework around it. It runs @'clear'@ before the render
+  function, and @'flush'@ / @'swapBuffers'@ afterwards.
+-}
+renderWrapper :: Scene -> IO ()
+renderWrapper scene = do
+  clear [ColorBuffer]
+
+  scene
+
+  flush
+  swapBuffers
diff --git a/src/FRP/Spice/Engine/RunInput.hs b/src/FRP/Spice/Engine/RunInput.hs
--- a/src/FRP/Spice/Engine/RunInput.hs
+++ b/src/FRP/Spice/Engine/RunInput.hs
@@ -1,31 +1,31 @@
-{-|
-  This module need not be used directly. Refer to @'FRP.Spice.Engine'@ instead.
--}
-module FRP.Spice.Engine.RunInput where
-
---------------------
--- Global Imports --
-import Graphics.Rendering.OpenGL
-import Graphics.UI.GLFW as GLFW
-import Data.IORef
-import GHC.Float
-
-----------
--- Code --
-
-{-|
-  Given an @'IORef'@ indicating whether or not the program should close, it
-  either returns the delta time since the last call, or a @'Nothing'@,
-  indicating that the program should close.
--}
-runInput :: IORef Bool -> IO (Maybe Float)
-runInput closed = do
-  pollEvents
-  c <- readIORef closed
-
-  if c
-    then return Nothing
-    else do
-      dt <- get GLFW.time
-      GLFW.time $= 0
-      return $ Just $ double2Float dt
+{-|
+  This module need not be used directly. Refer to @'FRP.Spice.Engine'@ instead.
+-}
+module FRP.Spice.Engine.RunInput where
+
+--------------------
+-- Global Imports --
+import Graphics.Rendering.OpenGL
+import Graphics.UI.GLFW as GLFW
+import Data.IORef
+import GHC.Float
+
+----------
+-- Code --
+
+{-|
+  Given an @'IORef'@ indicating whether or not the program should close, it
+  either returns the delta time since the last call, or a @'Nothing'@,
+  indicating that the program should close.
+-}
+runInput :: IORef Bool -> IO (Maybe Float)
+runInput closed = do
+  pollEvents
+  c <- readIORef closed
+
+  if c
+    then return Nothing
+    else do
+      dt <- get GLFW.time
+      GLFW.time $= 0
+      return $ Just $ double2Float dt
diff --git a/src/FRP/Spice/Game.hs b/src/FRP/Spice/Game.hs
--- a/src/FRP/Spice/Game.hs
+++ b/src/FRP/Spice/Game.hs
@@ -1,27 +1,29 @@
-{-|
-  This module provides the API which people must use to define a game within
-  the scope of Spice.
--}
-module FRP.Spice.Game where
-
--------------------
--- Local Imports --
-import FRP.Spice.Graphics.Scene
-import FRP.Spice.Input
-
-----------
--- Code --
-
-{-|
-  A synonym to make the update function more self-documenting.
--}
-type DeltaTime = Float
-
-{-|
-  The class which is to be used in the @'FRP.Spice.Engine.startEngine'@
-  function. @'update'@ provides the API to update on every tick (purely), an
-   @'render'@ provides the API to render every frame.
--}
-class Game a where
-  update :: DeltaTime -> Input -> a -> a
-  render :: a -> Scene
+{-|
+  This module provides the API which people must use to define a game within
+  the scope of Spice.
+-}
+module FRP.Spice.Game where
+
+-------------------
+-- Local Imports --
+import FRP.Spice.Graphics.Scene
+import FRP.Spice.Assets
+import FRP.Spice.Input
+
+----------
+-- Code --
+
+{-|
+  A synonym to make the update function more self-documenting.
+-}
+type DeltaTime = Float
+
+{-|
+  The class which is to be used in the @'FRP.Spice.Engine.startEngine'@
+  function. @'update'@ provides the API to update on every tick (purely), an
+   @'render'@ provides the API to render every frame.
+-}
+class Game a where
+  update :: DeltaTime -> Input -> a -> a
+  render :: Assets -> a -> Scene
+  loadAssets :: a -> LoadAssets
diff --git a/src/FRP/Spice/Graphics.hs b/src/FRP/Spice/Graphics.hs
--- a/src/FRP/Spice/Graphics.hs
+++ b/src/FRP/Spice/Graphics.hs
@@ -1,15 +1,17 @@
-{-|
-  This module re-exports a number of modules having to do with graphics.
--}
-module FRP.Spice.Graphics ( module FRP.Spice.Graphics.Geometry
-                          , module FRP.Spice.Graphics.Color
-                          , module FRP.Spice.Graphics.Scene
-                          , module FRP.Spice.Graphics.Utils
-                          ) where
-
------------------------
--- Rexported Imports --
-import FRP.Spice.Graphics.Geometry
-import FRP.Spice.Graphics.Color
-import FRP.Spice.Graphics.Scene
-import FRP.Spice.Graphics.Utils
+{-|
+  This module re-exports a number of modules having to do with graphics.
+-}
+module FRP.Spice.Graphics ( module FRP.Spice.Graphics.Geometry
+                          , module FRP.Spice.Graphics.Sprite
+                          , module FRP.Spice.Graphics.Color
+                          , module FRP.Spice.Graphics.Scene
+                          , module FRP.Spice.Graphics.Utils
+                          ) where
+
+-----------------------
+-- Rexported Imports --
+import FRP.Spice.Graphics.Geometry
+import FRP.Spice.Graphics.Sprite
+import FRP.Spice.Graphics.Color
+import FRP.Spice.Graphics.Scene
+import FRP.Spice.Graphics.Utils
diff --git a/src/FRP/Spice/Graphics/Color.hs b/src/FRP/Spice/Graphics/Color.hs
--- a/src/FRP/Spice/Graphics/Color.hs
+++ b/src/FRP/Spice/Graphics/Color.hs
@@ -1,92 +1,99 @@
-{-|
-  This module provides an abstraction over the default representations of color
-  in the Haskell OpenGL bindings.
--}
-module FRP.Spice.Graphics.Color where
-
--------------------
--- Local Imports --
-import FRP.Spice.Graphics.Element
-import FRP.Spice.Graphics.Scene
-
-----------
--- Code --
-
-{-|
-  Representing a Color using four @'Float'@ representing reg, green, blue, and
-  the alpha mask respectively. The @'Float'@s are in a range from 0-1,
-  representing @'Int'@s from 0-255.
--}
-data Color = Color { getRed   :: Float
-                   , getGreen :: Float
-                   , getBlue  :: Float
-                   , getAlpha :: Float
-                   }
-  deriving (Eq, Show, Read)
-
-{-|
-  Converting a color to an action in a @'Scene'@.
--}
-bindColor :: Color -> Scene
-bindColor (Color r g b a) = fromElements [SetColor r g b a]
-
-{-|
-  A synonym for the @'Color'@ constructor.
--}
-color4f :: Float -> Float -> Float -> Float -> Color
-color4f = Color
-
-{-|
-  Constructing a @'Color'@ from 3 @'Float'@s, defaulting the alpha mask to 1.0.
--}
-color3f :: Float -> Float -> Float -> Color
-color3f r g b = color4f r g b 1.0
-
-{-|
-  Creating a @'Color'@ from 4 @'Int'@s. The ints, similarly to @'color4f'@
-  represent red, green, blue, and the alpha mask respectively. The ints should
-  be in the range of 0-255. (Note: @'color4i'@ is functionally equivalent (and
-  also equivalent in source code) to calling color4f with each of its arguments
-  divided by 255.)
--}
-color4i :: Int -> Int -> Int -> Int -> Color
-color4i r g b a = color4f (fromIntegral r / 255)
-                          (fromIntegral g / 255)
-                          (fromIntegral b / 255)
-                          (fromIntegral a / 255)
-
-{-|
-  Constructing a @'Color'@ from 3 @'Int'@s, defaulting the alpha mask to 255.
--}
-color3i :: Int -> Int -> Int -> Color
-color3i r g b = color4i r g b 255
-
-{-|
-  The color black.
--}
-black :: Color
-black = color3i 0 0 0
-
-{-|
-  The color white.
--}
-white :: Color
-white = color3i 255 255 255
-
-{-|
-  The color red.
--}
-red :: Color
-red = color3i 255 0 0
-
-{-|
-  The color green.
--}
-green :: Color
-green = color3i 0 255 0
-
-{-|
-  The color blue.
--}
-blue :: Color
-blue = color3i 0 0 255
+{-|
+  This module provides an abstraction over the default representations of color
+  in the Haskell OpenGL bindings.
+-}
+module FRP.Spice.Graphics.Color  where
+
+--------------------
+-- Global Imports --
+import Graphics.Rendering.OpenGL ( Color4 (..)
+                                 , color
+                                 )
+
+-------------------
+-- Local Imports --
+import FRP.Spice.Graphics.Scene
+import FRP.Spice.Graphics.Utils
+
+----------
+-- Code --
+
+{-|
+  Representing a Color using four @'Float'@ representing reg, green, blue, and
+  the alpha mask respectively. The @'Float'@s are in a range from 0-1,
+  representing @'Int'@s from 0-255.
+-}
+data Color = Color { getRed   :: Float
+                   , getGreen :: Float
+                   , getBlue  :: Float
+                   , getAlpha :: Float
+                   }
+  deriving (Eq, Show, Read)
+
+{-|
+  Converting a color to an action in a @'Scene'@.
+-}
+bindColor :: Color -> Scene
+bindColor (Color r g b a) =
+  color $ Color4 (togl r) (togl g) (togl b) (togl a)
+
+{-|
+  A synonym for the @'Color'@ constructor.
+-}
+color4f :: Float -> Float -> Float -> Float -> Color
+color4f = Color
+
+{-|
+  Constructing a @'Color'@ from 3 @'Float'@s, defaulting the alpha mask to 1.0.
+-}
+color3f :: Float -> Float -> Float -> Color
+color3f r g b = color4f r g b 1.0
+
+{-|
+  Creating a @'Color'@ from 4 @'Int'@s. The ints, similarly to @'color4f'@
+  represent red, green, blue, and the alpha mask respectively. The ints should
+  be in the range of 0-255. (Note: @'color4i'@ is functionally equivalent (and
+  also equivalent in source code) to calling color4f with each of its arguments
+  divided by 255.)
+-}
+color4i :: Int -> Int -> Int -> Int -> Color
+color4i r g b a = color4f (fromIntegral r / 255)
+                          (fromIntegral g / 255)
+                          (fromIntegral b / 255)
+                          (fromIntegral a / 255)
+
+{-|
+  Constructing a @'Color'@ from 3 @'Int'@s, defaulting the alpha mask to 255.
+-}
+color3i :: Int -> Int -> Int -> Color
+color3i r g b = color4i r g b 255
+
+{-|
+  The color black.
+-}
+black :: Color
+black = color3i 0 0 0
+
+{-|
+  The color white.
+-}
+white :: Color
+white = color3i 255 255 255
+
+{-|
+  The color red.
+-}
+red :: Color
+red = color3i 255 0 0
+
+{-|
+  The color green.
+-}
+green :: Color
+green = color3i 0 255 0
+
+{-|
+  The color blue.
+-}
+blue :: Color
+blue = color3i 0 0 255
diff --git a/src/FRP/Spice/Graphics/Element.hs b/src/FRP/Spice/Graphics/Element.hs
deleted file mode 100644
--- a/src/FRP/Spice/Graphics/Element.hs
+++ /dev/null
@@ -1,41 +0,0 @@
-{-|
-  This module provides a unified API for specifying every kind of rendering
-  datatype and how they get rendered. All of this -- of course -- is only in
-  the scope the spice project.
--}
-module FRP.Spice.Graphics.Element ( Element (..)
-                                  , renderElement
-                                  ) where
-
---------------------
--- Global Imports --
-import Graphics.Rendering.OpenGL
-import Control.Monad
-
--------------------
--- Local Imports --
-import FRP.Spice.Graphics.Utils
-import FRP.Spice.Math
-
-----------
--- Code --
-
-{-|
-  A type to purely contain the information for any kind of render call (that
-  has been implemented so far.)
--}
-data Element = RenderPrimitive PrimitiveMode [Vector Float]
-             | RenderSprite (Vector Float) (Vector Float) Float
-             | SetColor Float Float Float Float
-
-{-|
-  Converting an @'Element'@ into its matching OpenGL call.
--}
-renderElement :: Element -> IO ()
-renderElement (RenderPrimitive mode vertecies) =
-  renderPrimitive mode $
-    forM_ vertecies $ \(Vector x y) ->
-      vertex $ Vertex2 (togl x) (togl y)
-renderElement (RenderSprite pos size rot) = return ()
-renderElement (SetColor r g b a) =
-  color $ Color4 (togl r) (togl g) (togl b) (togl a)
diff --git a/src/FRP/Spice/Graphics/Geometry.hs b/src/FRP/Spice/Graphics/Geometry.hs
--- a/src/FRP/Spice/Graphics/Geometry.hs
+++ b/src/FRP/Spice/Graphics/Geometry.hs
@@ -1,74 +1,76 @@
-{-|
-  This module provides a cleaner API to render a number of shapes in the
-  current OpenGL context.
--}
-module FRP.Spice.Graphics.Geometry ( renderPoint
-                                   , renderRectangle
-                                   , renderSquare
-                                   ) where
-
---------------------
--- Global Imports --
-import Graphics.Rendering.OpenGL
-
--------------------
--- Local Imports --
-import FRP.Spice.Graphics.Element
-import FRP.Spice.Graphics.Scene
-import FRP.Spice.Math.Vector
-
-----------
--- Code --
-
-{-|
-  Rendering a point.
--}
-renderPoint :: Vector Float -> Scene
-renderPoint pos =
-  fromElements [RenderPrimitive Points [pos]]
-
-{-|
-  Rendering a line between two points.
--}
-renderLine :: Vector Float -> Vector Float -> Scene
-renderLine p1 p2 =
-  fromElements [ RenderPrimitive Lines [ p1
-                                       , p2
-                                       ]
-               ]
-
-{-|
-  Rendering a rectangle.
--}
-renderRectangle :: Vector Float -> Vector Float -> Scene
-renderRectangle (Vector x y) (Vector w h) = do
-  fromElements [ RenderPrimitive Quads [ Vector (x    ) (y    )
-                                       , Vector (x + w) (y    )
-                                       , Vector (x + w) (y + h)
-                                       , Vector (x    ) (y + h)
-                                       ]
-               ]
-
-{-|
-  Rendering a square.
--}
-renderSquare :: Vector Float -> Float -> Scene
-renderSquare pos size = renderRectangle pos $ Vector size size
-
-{-|
-  Rendering a triangle.
--}
-renderTriangle :: Vector Float -> Vector Float -> Vector Float -> Scene
-renderTriangle p1 p2 p3 =
-  fromElements [ RenderPrimitive Triangles [ p1
-                                           , p2
-                                           , p3
-                                           ]
-               ]
-
-{-|
-  Rendering a polygon with 1-N vertecies.
--}
-renderPolygon :: [Vector Float] -> Scene
-renderPolygon l =
-  fromElements [RenderPrimitive Polygon l]
+{-|
+  This module provides a cleaner API to render a number of shapes in the
+  current OpenGL context.
+-}
+module FRP.Spice.Graphics.Geometry ( renderPoint
+                                   , renderLine
+                                   , renderRectangle
+                                   , renderSquare
+                                   , renderTriangle
+                                   , renderPolygon
+                                   ) where
+
+--------------------
+-- Global Imports --
+import Graphics.Rendering.OpenGL
+import Control.Monad
+
+-------------------
+-- Local Imports --
+import FRP.Spice.Graphics.Scene
+import FRP.Spice.Graphics.Utils
+import FRP.Spice.Math.Vector
+
+----------
+-- Code --
+
+{-|
+  A version of @'renderPrimitive'@ where it takes a list of @'Vector'@
+  @'Float'@s instead of performing @'vertex'@ calls.
+-}
+renderPrimitive' :: PrimitiveMode -> [Vector Float] -> Scene
+renderPrimitive' mode points =
+  renderPrimitive mode $
+    forM_ points $ \(Vector x y) ->
+      vertex $ Vertex2 (togl x) (togl y)
+
+{-|
+  Rendering a point.
+-}
+renderPoint :: Vector Float -> Scene
+renderPoint pos = renderPrimitive' Points [pos]
+
+{-|
+  Rendering a line between two points.
+-}
+renderLine :: Vector Float -> Vector Float -> Scene
+renderLine p1 p2 = renderPrimitive' Lines [p1, p2]
+
+{-|
+  Rendering a rectangle.
+-}
+renderRectangle :: Vector Float -> Vector Float -> Scene
+renderRectangle (Vector x y) (Vector w h) =
+  renderPrimitive' Quads [ Vector (x    ) (y    )
+                         , Vector (x + w) (y    )
+                         , Vector (x + w) (y + h)
+                         , Vector (x    ) (y + h)
+                         ]
+
+{-|
+  Rendering a square.
+-}
+renderSquare :: Vector Float -> Float -> Scene
+renderSquare pos size = renderRectangle pos $ Vector size size
+
+{-|
+  Rendering a triangle.
+-}
+renderTriangle :: Vector Float -> Vector Float -> Vector Float -> Scene
+renderTriangle p1 p2 p3 = renderPrimitive' Triangles [p1, p2, p3]
+
+{-|
+  Rendering a polygon with 1-N vertecies.
+-}
+renderPolygon :: [Vector Float] -> Scene
+renderPolygon l = renderPrimitive' Polygon l
diff --git a/src/FRP/Spice/Graphics/Scene.hs b/src/FRP/Spice/Graphics/Scene.hs
--- a/src/FRP/Spice/Graphics/Scene.hs
+++ b/src/FRP/Spice/Graphics/Scene.hs
@@ -1,24 +1,13 @@
-{-|
-  This module provides an API to compose @'Scene'@s through do-notation.
--}
-module FRP.Spice.Graphics.Scene where
-
--------------------
--- Local Imports --
-import FRP.Spice.Graphics.Element
-import FRP.Spice.Utils.DoList
-
-----------
--- Code --
-
-{-|
-  A DoList to compose a list of @'Element'@s to render using do-notation.
--}
-type Scene = DoList [Element]
-
-fromElements :: [Element] -> Scene
-fromElements = fromValues
-
-renderScene :: Scene -> IO ()
-renderScene scene =
-  mapM_ renderElement $ values scene
+{-|
+  This module provides an API to compose @'Scene'@s through do-notation.
+-}
+module FRP.Spice.Graphics.Scene where
+
+----------
+-- Code --
+
+{-|
+  A type synonym for a single IO () call to suggest that users should be
+  *rendering* in render calls, and not performing other IO.
+-}
+type Scene = IO ()
diff --git a/src/FRP/Spice/Graphics/Sprite.hs b/src/FRP/Spice/Graphics/Sprite.hs
new file mode 100644
--- /dev/null
+++ b/src/FRP/Spice/Graphics/Sprite.hs
@@ -0,0 +1,111 @@
+{-|
+  This module provides an API for loading and rendering textures in the form
+  of @'Sprite'@s.
+-}
+module FRP.Spice.Graphics.Sprite ( Sprite (..)
+                                 , renderSprite
+                                 , loadSprite
+                                 ) where
+
+--------------------
+-- Global Imports --
+import Graphics.Rendering.OpenGL
+import Data.ByteString.Unsafe
+import Control.Applicative
+import Codec.Picture.Repa
+import Codec.Picture
+import Control.Monad
+import Foreign.Ptr
+
+-------------------
+-- Local Imports --
+import FRP.Spice.Graphics.Color
+import FRP.Spice.Graphics.Scene
+import FRP.Spice.Graphics.Utils
+import FRP.Spice.Math
+
+----------
+-- Code --
+
+{-|
+  Getting the size from a @'DynamicImage'@.
+-}
+getInfo :: DynamicImage -> (Int, Int, PixelInternalFormat)
+getInfo (ImageRGB8   (Image w h _)) = (w, h, RGB8)
+getInfo (ImageRGB16  (Image w h _)) = (w, h, RGB16)
+getInfo (ImageRGBA8  (Image w h _)) = (w, h, RGBA8)
+getInfo (ImageRGBA16 (Image w h _)) = (w, h, RGBA16)
+
+{-|
+  Loading a @'TextureObject'@ and @'Size'@ from any RGB8, RGB16, RGBA8, or
+  RGBA16 images.
+-}
+loadTex :: FilePath -> IO (TextureObject, Size)
+loadTex path = do
+  img <- either error id <$> readImageRGBA path
+
+  let dynimg         = imgToImage img
+      (w, h, format) = getInfo dynimg
+      glSize         = TextureSize2D (fromIntegral w) (fromIntegral h)
+      bs             = toByteString img
+
+  ptr <- unsafeUseAsCString bs $ \cstr ->
+    return $ castPtr cstr
+
+  [t] <- genObjectNames 1
+
+  textureBinding Texture2D $= Just t
+  texImage2D Texture2D NoProxy 0 format glSize 0 (PixelData ABGR UnsignedByte ptr)
+
+  return (t, Size (fromIntegral w) (fromIntegral h))
+
+{-|
+  A datatype to represent a @'TextureObject'@ through a reference to the
+  @'TextureObject'@ itself and its @'Size'@.
+-}
+data Sprite = Sprite { spriteTex   :: TextureObject
+                     , spriteSize  :: Vector Float
+                     }
+
+{-|
+  Performing an OpenGL call to render the @'Sprite'@.
+-}
+renderSprite :: Sprite -> Vector Float -> Scene
+renderSprite sprite pos = do
+  textureWrapMode Texture2D S $= (Repeated, ClampToEdge)
+  textureWrapMode Texture2D T $= (Repeated, ClampToEdge)
+  textureFilter   Texture2D   $= ((Linear', Nothing), Linear')
+  textureFunction             $= Replace
+
+  texture        Texture2D $= Enabled
+  textureBinding Texture2D $= (Just $ spriteTex sprite)
+
+  renderPrimitive Quads $
+    forM_ (generateCoords pos $ spriteSize sprite) $ \(Vector x y, Vector tx ty) -> do
+      texCoord $ TexCoord2 (togl tx) (togl ty)
+      vertex $ Vertex2 (togl x) (togl y)
+
+  texture Texture2D        $= Disabled
+  where generateCoords :: Vector Float -> Vector Float -> [(Vector Float, Vector Float)]
+        generateCoords (Vector x y) (Vector w h) =
+          [ (Vector (x    ) (y    ), Vector 0 0)
+          , (Vector (x + w) (y    ), Vector 1 0)
+          , (Vector (x + w) (y + h), Vector 1 1)
+          , (Vector (x    ) (y + h), Vector 0 1)
+          ]
+
+{-|
+  Creating a @'Sprite'@ from a @'TextureObject'@.
+-}
+makeSprite :: (TextureObject, Size) -> Sprite
+makeSprite (to, (Size w h)) =
+  Sprite { spriteTex   = to
+         , spriteSize  = size
+         }
+  where size = Vector ((fromIntegral w) / 640) ((fromIntegral h) / 480)
+
+{-|
+  Loading a @'Sprite'@ from a file.
+-}
+loadSprite :: FilePath -> IO Sprite
+loadSprite = liftM makeSprite . loadTex
diff --git a/src/FRP/Spice/Graphics/Utils.hs b/src/FRP/Spice/Graphics/Utils.hs
--- a/src/FRP/Spice/Graphics/Utils.hs
+++ b/src/FRP/Spice/Graphics/Utils.hs
@@ -1,18 +1,24 @@
-{-|
-  This module provides a set of utilities to ease the burden of writing OpenGL
-  rendering functions.
--}
-module FRP.Spice.Graphics.Utils where
-
---------------------
--- Global Imports --
-import Graphics.Rendering.OpenGL
-
-----------
--- Code --
-
-{-|
-  Converting a @'Float'@ to a @'GLfloat'@
--}
-togl :: Float -> GLfloat
-togl = realToFrac
+{-|
+  This module provides a set of utilities to ease the burden of writing OpenGL
+  rendering functions.
+-}
+module FRP.Spice.Graphics.Utils where
+
+--------------------
+-- Global Imports --
+import Graphics.Rendering.OpenGL
+
+----------
+-- Code --
+
+{-|
+  Converting a @'Float'@ to a @'GLfloat'@
+-}
+togl :: Float -> GLfloat
+togl = realToFrac
+
+{-|
+  Converting a @'GLfloat'@ to a @'Float'@.
+-}
+fromgl :: GLfloat -> Float
+fromgl = realToFrac
diff --git a/src/FRP/Spice/Input.hs b/src/FRP/Spice/Input.hs
--- a/src/FRP/Spice/Input.hs
+++ b/src/FRP/Spice/Input.hs
@@ -1,26 +1,26 @@
-{-|
-  This module provides everything relating to input in the scope of spice.
--}
-module FRP.Spice.Input where
-
---------------------
--- Global Imports --
-import Graphics.UI.GLFW
-import Data.Map.Strict
-
--------------------
--- Local Imports --
-import FRP.Spice.Math
-
-----------
--- Code --
-
-{-|
-  A container for all of the states themselves. It is used as a @'Signal'@
-  @'Input'@ in the @'InputContainer'@ (which is necessary to use it within
-  Elerea's FRP network).
--}
-data Input = Input { mousePosition :: Vector Float
-                   , keyboard      :: Map Key Bool
-                   , mouse         :: Map MouseButton Bool
-                   }
+{-|
+  This module provides everything relating to input in the scope of spice.
+-}
+module FRP.Spice.Input where
+
+--------------------
+-- Global Imports --
+import Graphics.UI.GLFW
+import Data.Map.Strict
+
+-------------------
+-- Local Imports --
+import FRP.Spice.Math
+
+----------
+-- Code --
+
+{-|
+  A container for all of the states themselves. It is used as a @'Signal'@
+  @'Input'@ in the @'InputContainer'@ (which is necessary to use it within
+  Elerea's FRP network).
+-}
+data Input = Input { mousePosition :: Vector Float
+                   , keyboard      :: Map Key Bool
+                   , mouse         :: Map MouseButton Bool
+                   }
diff --git a/src/FRP/Spice/Input/Backend.hs b/src/FRP/Spice/Input/Backend.hs
--- a/src/FRP/Spice/Input/Backend.hs
+++ b/src/FRP/Spice/Input/Backend.hs
@@ -1,97 +1,97 @@
-{-|
-  The backend to be used with the input.
--}
-module FRP.Spice.Input.Backend where
-
---------------------
--- Global Imports --
-import Graphics.Rendering.OpenGL
-import Graphics.UI.GLFW as GLFW
-import FRP.Elerea.Param
-import Data.Map.Strict
-import Data.IORef
-
--------------------
--- Local Imports --
-import qualified FRP.Spice.Input.MousePosition as MousePosition
-import qualified FRP.Spice.Input.Keyboard      as Keyboard
-import qualified FRP.Spice.Input.Mouse         as Mouse
-import FRP.Spice.Input
-import FRP.Spice.Math
-
-----------
--- Code --
-
-{-|
-  A wrapper around the sinks for the mouse position, the key states, and the
-  mouse button states.
--}
-data Sinks = Sinks { mousePositionSinks :: Vector Float -> IO ()
-                   , keyboardSinks      :: Map Key (Bool -> IO ())
-                   , mouseSinks         :: Map MouseButton (Bool -> IO ())
-                   }
-
-
-
-{-|
-  A container around @'Sinks'@ and @'Signal'@ @'Input'@ so that one needn't
-  pass around a tuple.
--}
-data InputContainer = InputContainer { getSinks :: Sinks
-                                     , getInput :: Signal Input
-                                     }
-
-{-|
-  Making an @'InputContainer'@ filled with all necessary externals.
--}
-makeInputContainer :: IO InputContainer
-makeInputContainer = do
-  mousePositionExternals <- MousePosition.externals
-  keyboardExternals      <- Keyboard.externals
-  mouseExternals         <- Mouse.externals
-
-  let sinks = Sinks { mousePositionSinks = MousePosition.sinks mousePositionExternals
-                    , keyboardSinks      = Keyboard.sinks keyboardExternals
-                    , mouseSinks         = Mouse.sinks mouseExternals
-                    }
-
-  let input = do mps <- fst mousePositionExternals
-                 kbs <- Keyboard.signals keyboardExternals
-                 ms  <- Mouse.signals mouseExternals
-
-                 return Input { mousePosition = mps
-                              , keyboard      = kbs
-                              , mouse         = ms
-                              }
-
-  return InputContainer { getSinks = sinks
-                        , getInput = input
-                        }
-
-{-|
-  Creating a callback to update the mouse position's state.
--}
-makeMousePositionCallback :: InputContainer -> IORef (Vector Int) -> MousePosCallback
-makeMousePositionCallback ic wSizeRef (Position x y) = do
-  (Vector w h) <- readIORef wSizeRef
-  mousePositionSinks (getSinks ic) $
-    Vector (  fromIntegral x  / ((fromIntegral $ w) / 2) - 1)
-           ((-fromIntegral y) / ((fromIntegral $ h) / 2) + 1)
-
-{-|
-  Creating a callback to update the keyboard's states.
--}
-makeKeyboardCallback :: InputContainer -> KeyCallback
-makeKeyboardCallback ic key state =
-  keyboardSinks (getSinks ic) ! key $ case state of
-    Press   -> True
-    Release -> False
-
-{-|
-  Creating a callback to update the mouse buttons' states.
--}
-makeMouseCallback :: InputContainer -> MouseButtonCallback
-makeMouseCallback ic button state =
-  mouseSinks (getSinks ic) ! button $ case state of
-    Press   -> True
-    Release -> False
+{-|
+  The backend to be used with the input.
+-}
+module FRP.Spice.Input.Backend where
+
+--------------------
+-- Global Imports --
+import Graphics.Rendering.OpenGL
+import Graphics.UI.GLFW as GLFW
+import FRP.Elerea.Param
+import Data.Map.Strict
+import Data.IORef
+
+-------------------
+-- Local Imports --
+import qualified FRP.Spice.Input.MousePosition as MousePosition
+import qualified FRP.Spice.Input.Keyboard      as Keyboard
+import qualified FRP.Spice.Input.Mouse         as Mouse
+import FRP.Spice.Input
+import FRP.Spice.Math
+
+----------
+-- Code --
+
+{-|
+  A wrapper around the sinks for the mouse position, the key states, and the
+  mouse button states.
+-}
+data Sinks = Sinks { mousePositionSinks :: Vector Float -> IO ()
+                   , keyboardSinks      :: Map Key (Bool -> IO ())
+                   , mouseSinks         :: Map MouseButton (Bool -> IO ())
+                   }
+
+
+
+{-|
+  A container around @'Sinks'@ and @'Signal'@ @'Input'@ so that one needn't
+  pass around a tuple.
+-}
+data InputContainer = InputContainer { getSinks :: Sinks
+                                     , getInput :: Signal Input
+                                     }
+
+{-|
+  Making an @'InputContainer'@ filled with all necessary externals.
+-}
+makeInputContainer :: IO InputContainer
+makeInputContainer = do
+  mousePositionExternals <- MousePosition.externals
+  keyboardExternals      <- Keyboard.externals
+  mouseExternals         <- Mouse.externals
+
+  let sinks = Sinks { mousePositionSinks = MousePosition.sinks mousePositionExternals
+                    , keyboardSinks      = Keyboard.sinks keyboardExternals
+                    , mouseSinks         = Mouse.sinks mouseExternals
+                    }
+
+  let input = do mps <- fst mousePositionExternals
+                 kbs <- Keyboard.signals keyboardExternals
+                 ms  <- Mouse.signals mouseExternals
+
+                 return Input { mousePosition = mps
+                              , keyboard      = kbs
+                              , mouse         = ms
+                              }
+
+  return InputContainer { getSinks = sinks
+                        , getInput = input
+                        }
+
+{-|
+  Creating a callback to update the mouse position's state.
+-}
+makeMousePositionCallback :: InputContainer -> IORef (Vector Int) -> MousePosCallback
+makeMousePositionCallback ic wSizeRef (Position x y) = do
+  (Vector w h) <- readIORef wSizeRef
+  mousePositionSinks (getSinks ic) $
+    Vector (  fromIntegral x  / ((fromIntegral $ w) / 2) - 1)
+           ((-fromIntegral y) / ((fromIntegral $ h) / 2) + 1)
+
+{-|
+  Creating a callback to update the keyboard's states.
+-}
+makeKeyboardCallback :: InputContainer -> KeyCallback
+makeKeyboardCallback ic key state =
+  keyboardSinks (getSinks ic) ! key $ case state of
+    Press   -> True
+    Release -> False
+
+{-|
+  Creating a callback to update the mouse buttons' states.
+-}
+makeMouseCallback :: InputContainer -> MouseButtonCallback
+makeMouseCallback ic button state =
+  mouseSinks (getSinks ic) ! button $ case state of
+    Press   -> True
+    Release -> False
diff --git a/src/FRP/Spice/Input/Keyboard.hs b/src/FRP/Spice/Input/Keyboard.hs
--- a/src/FRP/Spice/Input/Keyboard.hs
+++ b/src/FRP/Spice/Input/Keyboard.hs
@@ -1,40 +1,40 @@
-{-|
-  The keyboard specific section of input.
--}
-module FRP.Spice.Input.Keyboard where
-
---------------------
--- Global Imports --
-import qualified Data.Traversable as T
-import Data.Map.Strict hiding (keys, map)
-import Graphics.UI.GLFW as GLFW
-import FRP.Elerea.Param
-import Control.Monad
-
-----------
--- Code --
-
-{-|
-  A list of all possible keys used in the GLFW API.
--}
-keys :: [Key]
-keys = map toEnum [0 .. 318]
-
-{-|
-  A Map from @'Key'@ to the externals created for every single key.
--}
-externals :: IO (Map Key (Signal Bool, Bool -> IO ()))
-externals = liftM fromList $ mapM (\k -> liftM ((,) k) $ external False) keys
-
-{-|
-  Creating the @'Signal'@ of a @'Map'@ from @'Key'@ to @'Bool'@ from a @'Map'@
-  of @'externals'@.
--}
-signals :: Map Key (Signal Bool, Bool -> IO ()) -> Signal (Map Key Bool)
-signals = T.sequence . fmap fst
-
-{-|
-  Making a @'Map'@ from @'Key'@ to sink from a @'Map'@ of @'externals'@.
--}
-sinks :: Map Key (Signal Bool, Bool -> IO ()) -> Map Key (Bool -> IO ())
-sinks = fmap snd
+{-|
+  The keyboard specific section of input.
+-}
+module FRP.Spice.Input.Keyboard where
+
+--------------------
+-- Global Imports --
+import qualified Data.Traversable as T
+import Data.Map.Strict hiding (keys, map)
+import Graphics.UI.GLFW as GLFW
+import FRP.Elerea.Param
+import Control.Monad
+
+----------
+-- Code --
+
+{-|
+  A list of all possible keys used in the GLFW API.
+-}
+keys :: [Key]
+keys = map toEnum [0 .. 318]
+
+{-|
+  A Map from @'Key'@ to the externals created for every single key.
+-}
+externals :: IO (Map Key (Signal Bool, Bool -> IO ()))
+externals = liftM fromList $ mapM (\k -> liftM ((,) k) $ external False) keys
+
+{-|
+  Creating the @'Signal'@ of a @'Map'@ from @'Key'@ to @'Bool'@ from a @'Map'@
+  of @'externals'@.
+-}
+signals :: Map Key (Signal Bool, Bool -> IO ()) -> Signal (Map Key Bool)
+signals = T.sequence . fmap fst
+
+{-|
+  Making a @'Map'@ from @'Key'@ to sink from a @'Map'@ of @'externals'@.
+-}
+sinks :: Map Key (Signal Bool, Bool -> IO ()) -> Map Key (Bool -> IO ())
+sinks = fmap snd
diff --git a/src/FRP/Spice/Input/Mouse.hs b/src/FRP/Spice/Input/Mouse.hs
--- a/src/FRP/Spice/Input/Mouse.hs
+++ b/src/FRP/Spice/Input/Mouse.hs
@@ -1,52 +1,52 @@
-{-|
-  The mouse (button) specific section of input.
--}
-module FRP.Spice.Input.Mouse where
-
---------------------
--- Global Imports --
-import qualified Data.Traversable as T (sequence)
-import Data.Map.Strict hiding (keys, map)
-import Graphics.UI.GLFW as GLFW
-import FRP.Elerea.Param
-import Control.Monad
-
-----------
--- Code --
-
-{-|
-  Adding an instance of Ord to MouseButton so it can be used with the map.
--}
-instance Ord MouseButton where
-  mb1 <= mb2 = fromEnum mb1 < fromEnum mb2
-
-{-|
-  A list of all mouse buttons available via the GLFW api.
--}
-buttons :: [MouseButton]
-buttons = [ ButtonLeft
-          , ButtonRight
-          , ButtonMiddle
-          ]
-          ++
-          map ButtonNo [0 .. 7]
-
-{-|
-  A map from @'MouseButton'@ to externals created for every button.
--}
-externals :: IO (Map MouseButton (Signal Bool, Bool -> IO ()))
-externals = liftM fromList $ mapM (\b -> liftM ((,) b) $ external False) buttons
-
-{-|
-  Creating the @'Signal'@ of a @'Map'@ from @'MouseButton'@ to @'Bool'@ from a
-  @'Map'@ of @'externals'@.
--}
-signals :: Map MouseButton (Signal Bool, Bool -> IO ()) -> Signal (Map MouseButton Bool)
-signals = T.sequence . fmap fst
-
-{-|
-  Making a @'Map'@ from @'MouseButton'@ to sink from a @'Map'@ of
-  @'externals'@.
--}
-sinks :: Map MouseButton (Signal Bool, Bool -> IO ()) -> Map MouseButton (Bool -> IO ())
-sinks = fmap snd
+{-|
+  The mouse (button) specific section of input.
+-}
+module FRP.Spice.Input.Mouse where
+
+--------------------
+-- Global Imports --
+import qualified Data.Traversable as T (sequence)
+import Data.Map.Strict hiding (keys, map)
+import Graphics.UI.GLFW as GLFW
+import FRP.Elerea.Param
+import Control.Monad
+
+----------
+-- Code --
+
+{-|
+  Adding an instance of Ord to MouseButton so it can be used with the map.
+-}
+instance Ord MouseButton where
+  mb1 <= mb2 = fromEnum mb1 < fromEnum mb2
+
+{-|
+  A list of all mouse buttons available via the GLFW api.
+-}
+buttons :: [MouseButton]
+buttons = [ ButtonLeft
+          , ButtonRight
+          , ButtonMiddle
+          ]
+          ++
+          map ButtonNo [0 .. 7]
+
+{-|
+  A map from @'MouseButton'@ to externals created for every button.
+-}
+externals :: IO (Map MouseButton (Signal Bool, Bool -> IO ()))
+externals = liftM fromList $ mapM (\b -> liftM ((,) b) $ external False) buttons
+
+{-|
+  Creating the @'Signal'@ of a @'Map'@ from @'MouseButton'@ to @'Bool'@ from a
+  @'Map'@ of @'externals'@.
+-}
+signals :: Map MouseButton (Signal Bool, Bool -> IO ()) -> Signal (Map MouseButton Bool)
+signals = T.sequence . fmap fst
+
+{-|
+  Making a @'Map'@ from @'MouseButton'@ to sink from a @'Map'@ of
+  @'externals'@.
+-}
+sinks :: Map MouseButton (Signal Bool, Bool -> IO ()) -> Map MouseButton (Bool -> IO ())
+sinks = fmap snd
diff --git a/src/FRP/Spice/Input/MousePosition.hs b/src/FRP/Spice/Input/MousePosition.hs
--- a/src/FRP/Spice/Input/MousePosition.hs
+++ b/src/FRP/Spice/Input/MousePosition.hs
@@ -1,31 +1,31 @@
-{-|
-  The mouse (position) specific section of input.
--}
-module FRP.Spice.Input.MousePosition where
-
---------------------
--- Global Imports --
-import FRP.Elerea.Param
-import Data.Default
-
--------------------
--- Local Imports --
-import FRP.Spice.Math.Vector
-
-{-|
-  Creating the external for the mouse position.
--}
-externals :: IO (Signal (Vector Float), Vector Float -> IO ())
-externals = external def
-
-{-|
-  Getting the signal from the mouse position external.
--}
-signals :: (Signal (Vector Float), Vector Float -> IO ()) -> Signal (Vector Float)
-signals = fst
-
-{-|
-  Getting the sink from the mouse position external.
--}
-sinks :: (Signal (Vector Float), Vector Float -> IO ()) -> Vector Float -> IO ()
-sinks = snd
+{-|
+  The mouse (position) specific section of input.
+-}
+module FRP.Spice.Input.MousePosition where
+
+--------------------
+-- Global Imports --
+import FRP.Elerea.Param
+import Data.Default
+
+-------------------
+-- Local Imports --
+import FRP.Spice.Math.Vector
+
+{-|
+  Creating the external for the mouse position.
+-}
+externals :: IO (Signal (Vector Float), Vector Float -> IO ())
+externals = external def
+
+{-|
+  Getting the signal from the mouse position external.
+-}
+signals :: (Signal (Vector Float), Vector Float -> IO ()) -> Signal (Vector Float)
+signals = fst
+
+{-|
+  Getting the sink from the mouse position external.
+-}
+sinks :: (Signal (Vector Float), Vector Float -> IO ()) -> Vector Float -> IO ()
+sinks = snd
diff --git a/src/FRP/Spice/Math.hs b/src/FRP/Spice/Math.hs
--- a/src/FRP/Spice/Math.hs
+++ b/src/FRP/Spice/Math.hs
@@ -1,9 +1,9 @@
-{-|
-  This module re-exports a number of modules having to do with math.
--}
-module FRP.Spice.Math ( module FRP.Spice.Math.Vector
-                      ) where
-
------------------------
--- Rexported Imports --
-import FRP.Spice.Math.Vector
+{-|
+  This module re-exports a number of modules having to do with math.
+-}
+module FRP.Spice.Math ( module FRP.Spice.Math.Vector
+                      ) where
+
+-----------------------
+-- Rexported Imports --
+import FRP.Spice.Math.Vector
diff --git a/src/FRP/Spice/Math/Vector.hs b/src/FRP/Spice/Math/Vector.hs
--- a/src/FRP/Spice/Math/Vector.hs
+++ b/src/FRP/Spice/Math/Vector.hs
@@ -1,64 +1,64 @@
-{-|
-  This module provides a @'Vector'@ datatype as described below.
--}
-module FRP.Spice.Math.Vector where
-
---------------------
--- Global Imports --
-import Control.Applicative
-import Data.Default
-import Data.Monoid
-
-----------
--- Code --
-
-{-|
-  A datatype that houses two values of a given type. It is provided with a
-  @'Num'@ instance so that, when used with number types it can function
-  similarly (though not exactly) to a mathematical vector.
--}
-data Vector a = Vector a a
-
-{-|
-  The default for the @'Vector'@.
--}
-instance Default a => Default (Vector a) where
-  def = Vector def def
-
-{-|
-  Displaying the @'Vector'@.
--}
-instance Show a => Show (Vector a) where
-  show (Vector x y) = mconcat ["Vector ", show x, " ", show y]
-
-{-|
-  Performs operations on the matching fields of the other @'Vector'@.
--}
-instance Num a => Num (Vector a) where
-  (Vector x1 y1) + (Vector x2 y2) = Vector (x1 + x2) (y1 + y2)
-  (Vector x1 y1) * (Vector x2 y2) = Vector (x1 * x2) (y1 * y2)
-
-  fromInteger n = Vector (fromInteger n) (fromInteger n)
-
-  abs    (Vector x y) = Vector (abs    x) (abs    y)
-  signum (Vector x y) = Vector (signum x) (signum y)
-  negate (Vector x y) = Vector (negate x) (negate y)
-
-{-|
-  Maps over both values in the @'Vector'@.
--}
-instance Functor Vector where
-  fmap fn (Vector x y) = Vector (fn x) (fn y)
-
-{-|
-  Applicative instance for @'Vector'@.
--}
-instance Applicative Vector where
-  pure a = Vector a a
-  (Vector fn _) <*> (Vector x y) = Vector (fn x) (fn y)
-
-{-|
-  Multiplying @'Vector'@ by a scalar value.
--}
-scalar :: Num a => Vector a -> a -> Vector a
-scalar (Vector x y) n = Vector (x * n) (y * n)
+{-|
+  This module provides a @'Vector'@ datatype as described below.
+-}
+module FRP.Spice.Math.Vector where
+
+--------------------
+-- Global Imports --
+import Control.Applicative
+import Data.Default
+import Data.Monoid
+
+----------
+-- Code --
+
+{-|
+  A datatype that houses two values of a given type. It is provided with a
+  @'Num'@ instance so that, when used with number types it can function
+  similarly (though not exactly) to a mathematical vector.
+-}
+data Vector a = Vector a a
+
+{-|
+  The default for the @'Vector'@.
+-}
+instance Default a => Default (Vector a) where
+  def = Vector def def
+
+{-|
+  Displaying the @'Vector'@.
+-}
+instance Show a => Show (Vector a) where
+  show (Vector x y) = mconcat ["Vector ", show x, " ", show y]
+
+{-|
+  Performs operations on the matching fields of the other @'Vector'@.
+-}
+instance Num a => Num (Vector a) where
+  (Vector x1 y1) + (Vector x2 y2) = Vector (x1 + x2) (y1 + y2)
+  (Vector x1 y1) * (Vector x2 y2) = Vector (x1 * x2) (y1 * y2)
+
+  fromInteger n = Vector (fromInteger n) (fromInteger n)
+
+  abs    (Vector x y) = Vector (abs    x) (abs    y)
+  signum (Vector x y) = Vector (signum x) (signum y)
+  negate (Vector x y) = Vector (negate x) (negate y)
+
+{-|
+  Maps over both values in the @'Vector'@.
+-}
+instance Functor Vector where
+  fmap fn (Vector x y) = Vector (fn x) (fn y)
+
+{-|
+  Applicative instance for @'Vector'@.
+-}
+instance Applicative Vector where
+  pure a = Vector a a
+  (Vector fn _) <*> (Vector x y) = Vector (fn x) (fn y)
+
+{-|
+  Multiplying @'Vector'@ by a scalar value.
+-}
+scalar :: Num a => Vector a -> a -> Vector a
+scalar (Vector x y) n = Vector (x * n) (y * n)
diff --git a/src/FRP/Spice/Utils/DoList.hs b/src/FRP/Spice/Utils/DoList.hs
--- a/src/FRP/Spice/Utils/DoList.hs
+++ b/src/FRP/Spice/Utils/DoList.hs
@@ -1,63 +1,63 @@
-{-|
-  This module provides a list that can be composed and concatenated through
-  do-notation.
-
-
--}
-module FRP.Spice.Utils.DoList where
-
---------------------
--- Global Imports --
-import Control.Applicative
-import Data.Monoid
-
-----------
--- Code --
-
-{-|
-  The datastructure itself. Almost equivalent to a tuple of length 2 without
-  and more context.
--}
-data DoListT a b = DoListT a b
-
-{-|
-  A more commonly used synonym for DoListT
--}
-type DoList a = DoListT a ()
-
-{-|
-  Getting the elements from a @'DoListT'@.
--}
-values :: DoListT a b -> a
-values (DoListT a _) = a
-
-{-|
-  Constructing a do-list from a @'Monoid'@.
--}
-fromValues :: Monoid a => a -> DoListT a ()
-fromValues a = DoListT a ()
-
-{-|
-  A functor instance to satisfy @'Applicative'@'s requirements.
--}
-instance Functor (DoListT a) where
-  fmap fn (DoListT a b) =
-    DoListT a $ fn b
-
-{-|
-  An applicative instance to satisfy @'Monad'@'s requirements.
--}
-instance Monoid a => Applicative (DoListT a) where
-  pure b = DoListT mempty b
-  (DoListT _ fn) <*> dl = fmap fn dl
-
-{-|
-  A monad instance to perform the actual composition of the list. List is a
-  loose word seeing as the monad instance simply needs an instance of
-  @'Monoid'@.
--}
-instance Monoid a => Monad (DoListT a) where
-  return = pure
-  (DoListT a b) >>= fn =
-    let (DoListT a' b') = fn b in
-      DoListT (mappend a a') b'
+{-|
+  This module provides a list that can be composed and concatenated through
+  do-notation.
+
+
+-}
+module FRP.Spice.Utils.DoList where
+
+--------------------
+-- Global Imports --
+import Control.Applicative
+import Data.Monoid
+
+----------
+-- Code --
+
+{-|
+  The datastructure itself. Almost equivalent to a tuple of length 2 without
+  and more context.
+-}
+data DoListT a b = DoListT a b
+
+{-|
+  A more commonly used synonym for DoListT
+-}
+type DoList a = DoListT a ()
+
+{-|
+  Getting the elements from a @'DoListT'@.
+-}
+values :: DoListT a b -> a
+values (DoListT a _) = a
+
+{-|
+  Constructing a do-list from a @'Monoid'@.
+-}
+fromValues :: Monoid a => a -> DoListT a ()
+fromValues a = DoListT a ()
+
+{-|
+  A functor instance to satisfy @'Applicative'@'s requirements.
+-}
+instance Functor (DoListT a) where
+  fmap fn (DoListT a b) =
+    DoListT a $ fn b
+
+{-|
+  An applicative instance to satisfy @'Monad'@'s requirements.
+-}
+instance Monoid a => Applicative (DoListT a) where
+  pure b = DoListT mempty b
+  (DoListT _ fn) <*> dl = fmap fn dl
+
+{-|
+  A monad instance to perform the actual composition of the list. List is a
+  loose word seeing as the monad instance simply needs an instance of
+  @'Monoid'@.
+-}
+instance Monoid a => Monad (DoListT a) where
+  return = pure
+  (DoListT a b) >>= fn =
+    let (DoListT a' b') = fn b in
+      DoListT (mappend a a') b'
