diff --git a/GLFW-b.cabal b/GLFW-b.cabal
--- a/GLFW-b.cabal
+++ b/GLFW-b.cabal
@@ -1,5 +1,5 @@
 name:         GLFW-b
-version:      1.4.8.1
+version:      1.4.8.2
 category:     Graphics
 
 author:       Brian Lewis <brian@lorf.org>
@@ -49,8 +49,9 @@
     Graphics.UI.GLFW.Types
 
   build-depends:
-    base           < 5,
-    bindings-GLFW >= 3.1.2.0
+      base          <  5
+    , deepseq       >= 1.1.0.0
+    , bindings-GLFW >= 3.1.2.3
 
 --------------------------------------------------------------------------------
 
@@ -64,13 +65,17 @@
   type: exitcode-stdio-1.0
 
   main-is: Test.hs
+  other-modules:
+    Graphics.UI.GLFW
+    Graphics.UI.GLFW.C
+    Graphics.UI.GLFW.Types
   build-depends:
-    GLFW-b,
-    HUnit                == 1.3.*,
-    base                  < 5,
-    bindings-GLFW        >= 3.1.2.0,
-    test-framework       == 0.8.*,
-    test-framework-hunit == 0.3.*
+      base                 <  5
+    , HUnit                >= 1.3 && < 1.7
+    , bindings-GLFW        >= 3.1.2.3
+    , deepseq              >= 1.1.0.0
+    , test-framework       == 0.8.*
+    , test-framework-hunit == 0.3.*
 
 --------------------------------------------------------------------------------
 
diff --git a/Graphics/UI/GLFW.hs b/Graphics/UI/GLFW.hs
--- a/Graphics/UI/GLFW.hs
+++ b/Graphics/UI/GLFW.hs
@@ -1,3 +1,21 @@
+{-|
+
+Threading restrictions which apply to the C version of GLFW still apply when
+writing @GLFW-b@ programs. See
+<http://www.glfw.org/docs/3.1/intro.html#thread_safety GLFW thread safety documentation>
+(applies here).
+
+Current context restructions which apply to the C version of GLFW still apply.
+See <http://www.glfw.org/docs/3.1/context.html#context_current  GLFW current context documentation>
+(applies here).
+
+@GLFW-b@ wraps callbacks and schedules them to be run after 'pollEvents' and
+'waitEvents' in the normal GHC runtime where they aren't subject to the usual
+GLFW reentrancy restrictions. See
+<http://www.glfw.org/docs/3.1/intro.html#reentrancy GLFW reentrancy documentation>
+(does not apply here).
+
+-}
 module Graphics.UI.GLFW
   ( -- * Error handling
     Error (..)
@@ -216,20 +234,35 @@
 
 --------------------------------------------------------------------------------
 
+-- | The error code and also a human-readable error message.
 type ErrorCallback           = Error -> String                                           -> IO ()
+-- | Fires when the window position changes.
 type WindowPosCallback       = Window -> Int -> Int                                      -> IO ()
+-- | Fires when the window is resized (in Screen Coordinates, which might not map 1:1 with pixels).
 type WindowSizeCallback      = Window -> Int -> Int                                      -> IO ()
+-- | Fires when the user is attempting to close the window
 type WindowCloseCallback     = Window                                                    -> IO ()
+-- | Fires when the contents of the window are damaged and they must be refreshed.
 type WindowRefreshCallback   = Window                                                    -> IO ()
+-- | Fires when the window gains or loses input focus.
 type WindowFocusCallback     = Window -> FocusState                                      -> IO ()
+-- | Fires when the window is iconified (minimized) or not.
 type WindowIconifyCallback   = Window -> IconifyState                                    -> IO ()
+-- | Fires when the size of the framebuffer for the window changes (in Pixels).
 type FramebufferSizeCallback = Window -> Int -> Int                                      -> IO ()
+-- | Fires whenever a mouse button is clicked.
 type MouseButtonCallback     = Window -> MouseButton -> MouseButtonState -> ModifierKeys -> IO ()
+-- | Fires every time the cursor position changes. Sub-pixel accuracy is used, when available.
 type CursorPosCallback       = Window -> Double -> Double                                -> IO ()
+-- | Fires when the cursor enters or exits the client area of the window.
 type CursorEnterCallback     = Window -> CursorState                                     -> IO ()
+-- | Fires when the user scrolls the mouse wheel or via touch gesture.
 type ScrollCallback          = Window -> Double -> Double                                -> IO ()
+-- | Fires for each press or repeat of keyboard keys (regardless of if it has textual meaning or not, eg Shift)
 type KeyCallback             = Window -> Key -> Int -> KeyState -> ModifierKeys          -> IO ()
+-- | Fires when a complete character codepoint is typed by the user, Shift then 'b' generates "B".
 type CharCallback            = Window -> Char                                            -> IO ()
+-- | Fires when a monitor is connected or disconnected.
 type MonitorCallback         = Monitor -> MonitorState                                   -> IO ()
 
 -- 3.1 additions
@@ -291,6 +324,8 @@
 --------------------------------------------------------------------------------
 -- Error handling
 
+-- | Can (and probably should) be used before GLFW initialization.
+-- See <http://www.glfw.org/docs/3.1/group__init.html#gaa5d796c3cf7c1a7f02f845486333fb5f glfwSetErrorCallback>
 setErrorCallback :: Maybe ErrorCallback -> IO ()
 setErrorCallback = setCallback
     mk'GLFWerrorfun
@@ -303,10 +338,20 @@
 --------------------------------------------------------------------------------
 -- Initialization and version information
 
+-- | Attempts to initialize the GLFW library. When the library is not initialized, the only
+-- allowed functions to call are 'getVersion', 'getVersionString', 'setErrorCallback',
+-- 'init', and 'terminate'. Returns if the initialization was successful or not.
+-- See <http://www.glfw.org/docs/3.1/group__init.html#ga317aac130a235ab08c6db0834907d85e glfwInit>
+-- and <http://www.glfw.org/docs/3.1/intro.html#intro_init Initialization and Termination>
 init :: IO Bool
 init =
     fromC `fmap` c'glfwInit
 
+-- | Cleans up GLFW and puts the library into an uninitialized state.
+-- Once you call this, you must initilize the library again.
+-- Warning: No window's context may be current in another thread when this is called.
+-- See <http://www.glfw.org/docs/3.1/group__init.html#gaaae48c0a18607ea4a4ba951d939f0901 glfwTerminate>
+-- and <http://www.glfw.org/docs/3.1/intro.html#intro_init Initialization and Termination>
 terminate :: IO ()
 terminate = do
     c'glfwTerminate
@@ -314,6 +359,8 @@
     storeCallback storedErrorFun           nullFunPtr
     storeCallback storedMonitorFun         nullFunPtr
 
+-- | Gets the version of the GLFW library that's being used with the current program.
+-- See <http://www.glfw.org/docs/3.1/group__init.html#ga9f8ffaacf3c269cc48eafbf8b9b71197 glfwGetVersion>
 getVersion :: IO Version
 getVersion =
     allocaArray 3 $ \p -> do
@@ -326,6 +373,10 @@
         v2 <- fromC `fmap` peek p2
         return $ Version v0 v1 v2
 
+-- | Gets the compile-time version string of the GLFW library binary.
+-- Gives extra info like platform and compile time options used, but you should not
+-- attempt to parse this to get the GLFW version number. Use 'getVersion' instead.
+-- See <http://www.glfw.org/docs/3.1/group__init.html#ga23d47dc013fce2bf58036da66079a657 glfwGetVersionString>
 getVersionString :: IO (Maybe String)
 getVersionString = do
     p'vs <- c'glfwGetVersionString
@@ -336,6 +387,8 @@
 --------------------------------------------------------------------------------
 -- Monitor handling
 
+-- | Gets the list of available monitors, if possible.
+-- See <http://www.glfw.org/docs/latest/group__monitor.html#ga3fba51c8bd36491d4712aa5bd074a537 glfwGetMonitors>
 getMonitors :: IO (Maybe [Monitor])
 getMonitors =
     alloca $ \p'n -> do
@@ -345,6 +398,8 @@
           then return Nothing
           else (Just . map fromC) `fmap` peekArray n p'mon
 
+-- | Gets the primary monitor.
+-- See <http://www.glfw.org/docs/latest/group__monitor.html#ga721867d84c6d18d6790d64d2847ca0b1 glfwGetPrimaryMonitor>
 getPrimaryMonitor :: IO (Maybe Monitor)
 getPrimaryMonitor = do
     p'mon <- c'glfwGetPrimaryMonitor
@@ -353,6 +408,8 @@
         then Nothing
         else Just $ fromC p'mon
 
+-- | Gets the position of the specified monitor within the coordinate space.
+-- See <http://www.glfw.org/docs/latest/group__monitor.html#ga102f54e7acc9149edbcf0997152df8c9 glfwGetMonitorPos>
 getMonitorPos :: Monitor -> IO (Int, Int)
 getMonitorPos mon =
     allocaArray 2 $ \p -> do
@@ -363,6 +420,8 @@
         y <- fromC `fmap` peek p'y
         return (x, y)
 
+-- | The physical width and height of the monitor.
+-- See <http://www.glfw.org/docs/latest/group__monitor.html#ga7d8bffc6c55539286a6bd20d32a8d7ea glfwGetMonitorPhysicalSize>
 getMonitorPhysicalSize :: Monitor -> IO (Int, Int)
 getMonitorPhysicalSize mon =
     allocaArray 2 $ \p -> do
@@ -373,6 +432,8 @@
         h <- fromC `fmap` peek p'h
         return (w, h)
 
+-- | A human-readable name for the monitor specified.
+-- See <http://www.glfw.org/docs/latest/group__monitor.html#ga79a34ee22ff080ca954a9663e4679daf getMonitorName>
 getMonitorName :: Monitor -> IO (Maybe String)
 getMonitorName mon = do
     p'name <- c'glfwGetMonitorName (toC mon)
@@ -380,6 +441,8 @@
       then return Nothing
       else Just `fmap` peekCString p'name
 
+-- | Sets a callback for when a monitor is connected or disconnected.
+-- See <http://www.glfw.org/docs/latest/group__monitor.html#gac3fe0f647f68b731f99756cd81897378 glfwSetMonitorCallback>
 setMonitorCallback :: Maybe MonitorCallback -> IO ()
 setMonitorCallback = setCallback
     mk'GLFWmonitorfun
@@ -387,6 +450,8 @@
     c'glfwSetMonitorCallback
     storedMonitorFun
 
+-- | Obtains the possible video modes of the monitor.
+-- See <http://www.glfw.org/docs/latest/group__monitor.html#ga820b0ce9a5237d645ea7cbb4bd383458 glfwGetVideoModes>
 getVideoModes :: Monitor -> IO (Maybe [VideoMode])
 getVideoModes mon =
     alloca $ \p'n -> do
@@ -396,6 +461,8 @@
           then return Nothing
           else (Just . map fromC) `fmap` peekArray n p'vms
 
+-- | Gets the active video mode of the monitor.
+-- See <http://www.glfw.org/docs/latest/group__monitor.html#gafc1bb972a921ad5b3bd5d63a95fc2d52 glfwGetVideoMode>
 getVideoMode :: Monitor -> IO (Maybe VideoMode)
 getVideoMode mon = do
     p'vm <- c'glfwGetVideoMode (toC mon)
@@ -403,10 +470,14 @@
       then return Nothing
       else (Just . fromC) `fmap` peek p'vm
 
+-- | Sets the gamma of a monitor.
+-- See <http://www.glfw.org/docs/latest/group__monitor.html#ga6ac582625c990220785ddd34efa3169a glfwSetGamma>
 setGamma :: Monitor -> Double -> IO ()
 setGamma mon e =
     c'glfwSetGamma (toC mon) (toC e)
 
+-- | Gets the gamma ramp in use with the monitor.
+-- See <http://www.glfw.org/docs/latest/group__monitor.html#gab7c41deb2219bde3e1eb756ddaa9ec80 glfwGetGammaRamp>
 getGammaRamp :: Monitor -> IO (Maybe GammaRamp)
 getGammaRamp m = do
     p'ggr <- c'glfwGetGammaRamp (toC m)
@@ -431,6 +502,8 @@
                   , gammaRampBlue  = bs
                   }
 
+-- | Assigns a gamma ramp to use with the given monitor.
+-- See <http://www.glfw.org/docs/latest/group__monitor.html#ga583f0ffd0d29613d8cd172b996bbf0dd glfwSetGammaRamp>
 setGammaRamp :: Monitor -> GammaRamp -> IO ()
 setGammaRamp mon gr =
     let rs = map toC $ gammaRampRed   gr :: [CUShort]
@@ -455,10 +528,14 @@
 --------------------------------------------------------------------------------
 -- Window handling
 
+-- | Sets all the window hints to default.
+-- See <http://www.glfw.org/docs/latest/group__window.html#gaa77c4898dfb83344a6b4f76aa16b9a4a glfwDefaultWindowHints>
 defaultWindowHints :: IO ()
 defaultWindowHints =
     c'glfwDefaultWindowHints
 
+-- | Hints something to the GLFW windowing system.
+-- See <http://www.glfw.org/docs/latest/group__window.html#ga7d9c8c62384b1e2821c4dc48952d2033 glfwWindowHint>
 windowHint :: WindowHint -> IO ()
 windowHint wh =
     let (t, v) = unpack
@@ -494,6 +571,7 @@
 -- | Creates a new window.
 -- Note: If running in GHCI don't forget to `:set -fno-ghci-sandbox` or you
 -- may run into an assertion failure, segfault or other nasty crash.
+-- See <http://www.glfw.org/docs/latest/group__window.html#ga5c336fddf2cbb5b92f65f10fb6043344 glfwCreateWindow>
 createWindow :: Int -- ^ Desired width for the window.
              -> Int -- ^ Desired height for the window.
              -> String -- ^ Desired title for the window.
@@ -545,6 +623,8 @@
                   c'glfwSetWindowUserPointer p'win (castStablePtrToPtr callbackPtr)
                   return $ Just $ fromC p'win
 
+-- | Cleans up a window and all associated resources
+-- See <http://www.glfw.org/docs/latest/group__window.html#gacdf43e51376051d2c091662e9fe3d7b2 glfwDestroyWindow>
 destroyWindow :: Window -> IO ()
 destroyWindow win = do
     pcb <- castPtrToStablePtr `liftM` c'glfwGetWindowUserPointer (toC win)
@@ -568,19 +648,26 @@
     free storedWindowSizeFun
     freeStablePtr pcb
 
-
+-- | If the window should close or not.
+-- See <http://www.glfw.org/docs/latest/group__window.html#ga24e02fbfefbb81fc45320989f8140ab5 glfwWindowShouldClose>
 windowShouldClose :: Window -> IO Bool
 windowShouldClose win =
     fromC `fmap` c'glfwWindowShouldClose (toC win)
 
+-- | Sets if the window should close or not.
+-- See <http://www.glfw.org/docs/latest/group__window.html#ga49c449dde2a6f87d996f4daaa09d6708 glfwSetWindowShouldClose>
 setWindowShouldClose :: Window -> Bool -> IO ()
 setWindowShouldClose win b =
     c'glfwSetWindowShouldClose (toC win) (toC b)
 
+-- | Sets the Title string of the window.
+-- See <http://www.glfw.org/docs/latest/group__window.html#ga5d877f09e968cef7a360b513306f17ff glfwSetWindowTitle>
 setWindowTitle :: Window -> String -> IO ()
 setWindowTitle win title =
     withCString title $ c'glfwSetWindowTitle (toC win)
 
+-- | Gets the window's position (in Screen Coordinates).
+-- See <http://www.glfw.org/docs/latest/group__window.html#ga73cb526c000876fd8ddf571570fdb634 glfwGetWindowPos>
 getWindowPos :: Window -> IO (Int, Int)
 getWindowPos win =
     allocaArray 2 $ \p -> do
@@ -591,10 +678,14 @@
         y <- fromC `fmap` peek p'y
         return (x, y)
 
+-- | Sets the window's position (in Screen Coordinates).
+-- See <http://www.glfw.org/docs/latest/group__window.html#ga1abb6d690e8c88e0c8cd1751356dbca8 glfwSetWindowPos>
 setWindowPos :: Window -> Int -> Int -> IO ()
 setWindowPos win x y =
     c'glfwSetWindowPos (toC win) (toC x) (toC y)
 
+-- | Gets the size of the window (in Screen Coordinates).
+-- See <http://www.glfw.org/docs/latest/group__window.html#gaeea7cbc03373a41fb51cfbf9f2a5d4c6 glfwGetWindowSize>
 getWindowSize :: Window -> IO (Int, Int)
 getWindowSize win =
     allocaArray 2 $ \p -> do
@@ -605,10 +696,14 @@
         h <- fromC `fmap` peek p'h
         return (w, h)
 
+-- | Sets the size of the client area for the window (in Screen Coordinates).
+-- See <http://www.glfw.org/docs/latest/group__window.html#ga371911f12c74c504dd8d47d832d095cb glfwSetWindowSize>
 setWindowSize :: Window -> Int -> Int -> IO ()
 setWindowSize win w h =
     c'glfwSetWindowSize (toC win) (toC w) (toC h)
 
+-- | The size of the framebuffer (in Pixels)
+-- See <http://www.glfw.org/docs/latest/group__window.html#ga0e2637a4161afb283f5300c7f94785c9 glfwGetFramebufferSize>
 getFramebufferSize :: Window -> IO (Int, Int)
 getFramebufferSize win =
     allocaArray 2 $ \p -> do
@@ -619,22 +714,32 @@
         h <- fromC `fmap` peek p'h
         return (w, h)
 
+-- | Iconifies (minimizes) the window.
+-- See <http://www.glfw.org/docs/latest/group__window.html#ga1bb559c0ebaad63c5c05ad2a066779c4 glfwIconifyWindow>
 iconifyWindow :: Window -> IO ()
 iconifyWindow =
     c'glfwIconifyWindow . toC
 
+-- | Restores the window from an iconified/minimized state.
+-- See <http://www.glfw.org/docs/latest/group__window.html#ga52527a5904b47d802b6b4bb519cdebc7 glfwRestoreWindow>
 restoreWindow :: Window -> IO ()
 restoreWindow =
     c'glfwRestoreWindow . toC
 
+-- | Shows the window.
+-- See <http://www.glfw.org/docs/latest/group__window.html#ga61be47917b72536a148300f46494fc66 glfwShowWindow>
 showWindow :: Window -> IO ()
 showWindow =
     c'glfwShowWindow . toC
 
+-- | Hides the window.
+-- See <http://www.glfw.org/docs/latest/group__window.html#ga49401f82a1ba5f15db5590728314d47c glfwHideWindow>
 hideWindow :: Window -> IO ()
 hideWindow =
     c'glfwHideWindow . toC
 
+-- | Gets the monitor that this window is running on.
+-- See <http://www.glfw.org/docs/latest/group__window.html#gaeac25e64789974ccbe0811766bd91a16 glfwGetWindowMonitor>
 getWindowMonitor :: Window -> IO (Maybe Monitor)
 getWindowMonitor win = do
     p'mon <- c'glfwGetWindowMonitor (toC win)
@@ -642,66 +747,96 @@
       then Nothing
       else Just $ fromC p'mon
 
+-- | Sets the position of the cursor within the window.
+-- See <http://www.glfw.org/docs/latest/group__input.html#ga04b03af936d906ca123c8f4ee08b39e7 glfwSetCursorPos>
 setCursorPos :: Window -> Double -> Double -> IO ()
 setCursorPos win x y =
     c'glfwSetCursorPos (toC win) (toC x) (toC y)
 
 -- start of functions related to c'glfwGetWindowAttrib
 
+-- | If the window has focus or not.
+-- See <http://www.glfw.org/docs/latest/group__window.html#gacccb29947ea4b16860ebef42c2cb9337 glfwGetWindowAttrib>
 getWindowFocused :: Window -> IO FocusState
 getWindowFocused win =
     fromC `fmap` c'glfwGetWindowAttrib (toC win) c'GLFW_FOCUSED
 
+-- | If the window is iconified (minimized) or not.
+-- See <http://www.glfw.org/docs/latest/group__window.html#gacccb29947ea4b16860ebef42c2cb9337 glfwGetWindowAttrib>
 getWindowIconified :: Window -> IO IconifyState
 getWindowIconified win =
     fromC `fmap` c'glfwGetWindowAttrib (toC win) c'GLFW_ICONIFIED
 
+-- | If the window is resizable or not.
+-- See <http://www.glfw.org/docs/latest/group__window.html#gacccb29947ea4b16860ebef42c2cb9337 glfwGetWindowAttrib>
 getWindowResizable :: Window -> IO Bool
 getWindowResizable win =
     fromC `fmap` c'glfwGetWindowAttrib (toC win) c'GLFW_RESIZABLE
 
+-- | If the window is decorated or not.
+-- See <http://www.glfw.org/docs/latest/group__window.html#gacccb29947ea4b16860ebef42c2cb9337 glfwGetWindowAttrib>
 getWindowDecorated :: Window -> IO Bool
 getWindowDecorated win =
     fromC `fmap` c'glfwGetWindowAttrib (toC win) c'GLFW_DECORATED
 
+-- | If the window is visible or not.
+-- See <http://www.glfw.org/docs/latest/group__window.html#gacccb29947ea4b16860ebef42c2cb9337 glfwGetWindowAttrib>
 getWindowVisible :: Window -> IO Bool
 getWindowVisible win =
     fromC `fmap` c'glfwGetWindowAttrib (toC win) c'GLFW_VISIBLE
 
+-- | The client api for this window.
+-- See <http://www.glfw.org/docs/latest/group__window.html#gacccb29947ea4b16860ebef42c2cb9337 glfwGetWindowAttrib>
 getWindowClientAPI :: Window -> IO ClientAPI
 getWindowClientAPI win =
     fromC `fmap` c'glfwGetWindowAttrib (toC win) c'GLFW_CLIENT_API
 
+-- | The context's "major" version, x.0.0
+-- See <http://www.glfw.org/docs/latest/group__window.html#gacccb29947ea4b16860ebef42c2cb9337 glfwGetWindowAttrib>
 getWindowContextVersionMajor :: Window -> IO Int
 getWindowContextVersionMajor win =
     fromC `fmap` c'glfwGetWindowAttrib (toC win) c'GLFW_CONTEXT_VERSION_MAJOR
 
+-- | The context's "minor" version, 0.y.0
+-- See <http://www.glfw.org/docs/latest/group__window.html#gacccb29947ea4b16860ebef42c2cb9337 glfwGetWindowAttrib>
 getWindowContextVersionMinor :: Window -> IO Int
 getWindowContextVersionMinor win =
     fromC `fmap` c'glfwGetWindowAttrib (toC win) c'GLFW_CONTEXT_VERSION_MINOR
 
+-- | The context's "revision" version, 0.0.z
+-- See <http://www.glfw.org/docs/latest/group__window.html#gacccb29947ea4b16860ebef42c2cb9337 glfwGetWindowAttrib>
 getWindowContextVersionRevision :: Window -> IO Int
 getWindowContextVersionRevision win =
     fromC `fmap` c'glfwGetWindowAttrib (toC win) c'GLFW_CONTEXT_REVISION
 
+-- | The context robustness of this window.
+-- See <http://www.glfw.org/docs/latest/group__window.html#gacccb29947ea4b16860ebef42c2cb9337 glfwGetWindowAttrib>
 getWindowContextRobustness :: Window -> IO ContextRobustness
 getWindowContextRobustness win =
     fromC `fmap` c'glfwGetWindowAttrib (toC win) c'GLFW_CONTEXT_ROBUSTNESS
 
+-- | If this window is set for opengl to be forward compatible.
+-- See <http://www.glfw.org/docs/latest/group__window.html#gacccb29947ea4b16860ebef42c2cb9337 glfwGetWindowAttrib>
 getWindowOpenGLForwardCompat :: Window -> IO Bool
 getWindowOpenGLForwardCompat win =
     fromC `fmap` c'glfwGetWindowAttrib (toC win) c'GLFW_OPENGL_FORWARD_COMPAT
 
+-- | If the window has an opengl debug context
+-- See <http://www.glfw.org/docs/latest/group__window.html#gacccb29947ea4b16860ebef42c2cb9337 glfwGetWindowAttrib>
 getWindowOpenGLDebugContext :: Window -> IO Bool
 getWindowOpenGLDebugContext win =
     fromC `fmap` c'glfwGetWindowAttrib (toC win) c'GLFW_OPENGL_DEBUG_CONTEXT
 
+-- | Obtains the current opengl profile.
+-- See <http://www.glfw.org/docs/latest/group__window.html#gacccb29947ea4b16860ebef42c2cb9337 glfwGetWindowAttrib>
 getWindowOpenGLProfile :: Window -> IO OpenGLProfile
 getWindowOpenGLProfile win =
     fromC `fmap` c'glfwGetWindowAttrib (toC win) c'GLFW_OPENGL_PROFILE
 
 -- end of functions related to c'glfwGetWindowAttrib
 
+-- | Sets the callback to use when the window position changes.
+-- See <http://www.glfw.org/docs/latest/group__window.html#ga2837d4d240659feb4268fcb6530a6ba1 glfwSetWindowPosCallback>
 setWindowPosCallback :: Window -> Maybe WindowPosCallback -> IO ()
 setWindowPosCallback win = setWindowCallback
     mk'GLFWwindowposfun
@@ -711,6 +846,8 @@
     storedWindowPosFun
     win
 
+-- | Sets the callback to use when the window's size changes.
+-- See <http://www.glfw.org/docs/latest/group__window.html#gaa40cd24840daa8c62f36cafc847c72b6 glfwSetWindowSizeCallback>
 setWindowSizeCallback :: Window -> Maybe WindowSizeCallback -> IO ()
 setWindowSizeCallback win = setWindowCallback
     mk'GLFWwindowsizefun
@@ -720,6 +857,8 @@
     storedWindowSizeFun
     win
 
+-- | Sets the callback to use when the user attempts to close the window.
+-- See <http://www.glfw.org/docs/latest/group__window.html#gaade9264e79fae52bdb78e2df11ee8d6a glfwSetWindowCloseCallback>
 setWindowCloseCallback :: Window -> Maybe WindowCloseCallback -> IO ()
 setWindowCloseCallback win = setWindowCallback
     mk'GLFWwindowclosefun
@@ -728,6 +867,8 @@
     storedWindowCloseFun
     win
 
+-- | Sets the callback to use when the window's data is partly dead and it should refresh.
+-- See <http://www.glfw.org/docs/latest/group__window.html#ga4569b76e8ac87c55b53199e6becd97eb glfwSetWindowRefreshCallback>
 setWindowRefreshCallback :: Window -> Maybe WindowRefreshCallback -> IO ()
 setWindowRefreshCallback win = setWindowCallback
     mk'GLFWwindowrefreshfun
@@ -736,6 +877,8 @@
     storedWindowRefreshFun
     win
 
+-- | Sets the callback to use when the window gains or loses focus.
+-- See <http://www.glfw.org/docs/latest/group__window.html#ga25d1c584edb375d7711c5c3548ba711f glfwSetWindowFocusCallback>
 setWindowFocusCallback :: Window -> Maybe WindowFocusCallback -> IO ()
 setWindowFocusCallback win = setWindowCallback
     mk'GLFWwindowfocusfun
@@ -744,6 +887,8 @@
     storedWindowFocusFun
     win
 
+-- | Sets the callback to use when the window is iconified or not (aka, minimized or not).
+-- See <http://www.glfw.org/docs/latest/group__window.html#gab1ea7263081c0e073b8d5b91d6ffd367 glfwSetWindowIconifyCallback>
 setWindowIconifyCallback :: Window -> Maybe WindowIconifyCallback -> IO ()
 setWindowIconifyCallback win = setWindowCallback
     mk'GLFWwindowiconifyfun
@@ -752,6 +897,8 @@
     storedWindowIconifyFun
     win
 
+-- | Sets the callback to use when the framebuffer's size changes.
+-- See <http://www.glfw.org/docs/latest/group__window.html#ga3203461a5303bf289f2e05f854b2f7cf glfwSetFramebufferSizeCallback>
 setFramebufferSizeCallback :: Window -> Maybe FramebufferSizeCallback -> IO ()
 setFramebufferSizeCallback win = setWindowCallback
     mk'GLFWframebuffersizefun
@@ -760,12 +907,23 @@
     storedFramebufferSizeFun
     win
 
+-- | Checks for any pending events, processes them, and then immediately returns.
+-- This is most useful for continual rendering, such as games.
+-- See the <http://www.glfw.org/docs/3.1/input.html#events Event Processing Guide>
 pollEvents :: IO ()
 pollEvents = c'glfwPollEvents >> executeScheduled
 
+-- | Waits until at least one event is in the queue then processes the queue and returns.
+-- Requires at least one window to be active for it to sleep. This saves a lot of CPU, and
+-- is better if you're doing only periodic rendering, such as with an editor program.
+-- See the <http://www.glfw.org/docs/3.1/input.html#events Event Processing Guide>
 waitEvents :: IO ()
 waitEvents = c'glfwWaitEvents >> executeScheduled
 
+-- | Creates an empty event within the event queue. Can be called from any
+-- thread, so you can use this to wake up the main thread that's using
+-- 'waitEvents' from a secondary thread.
+-- See the <http://www.glfw.org/docs/3.1/input.html#events Event Processing Guide>
 postEmptyEvent :: IO ()
 postEmptyEvent = c'glfwPostEmptyEvent
 
@@ -774,40 +932,62 @@
 
 -- start of glfw{GS}etInputMode-related functions
 
+-- | Gets the current cursor input mode.
+-- See <http://www.glfw.org/docs/3.1/group__input.html#gaa92336e173da9c8834558b54ee80563b glfwSetInputMode>
 getCursorInputMode :: Window -> IO CursorInputMode
 getCursorInputMode win =
     fromC `fmap` c'glfwGetInputMode (toC win) c'GLFW_CURSOR
 
+-- | Set the cursor input mode.
+-- See <http://www.glfw.org/docs/3.1/group__input.html#gaa92336e173da9c8834558b54ee80563b glfwSetInputMode>
 setCursorInputMode :: Window -> CursorInputMode -> IO ()
 setCursorInputMode win c =
     c'glfwSetInputMode (toC win) c'GLFW_CURSOR (toC c)
 
+-- | Gets the current sticky keys mode.
+-- See <http://www.glfw.org/docs/3.1/group__input.html#gaa92336e173da9c8834558b54ee80563b glfwSetInputMode>
 getStickyKeysInputMode :: Window -> IO StickyKeysInputMode
 getStickyKeysInputMode win =
     fromC `fmap` c'glfwGetInputMode (toC win) c'GLFW_STICKY_KEYS
 
+-- | Sets if sticky keys should be used or not.
+-- See <http://www.glfw.org/docs/3.1/group__input.html#gaa92336e173da9c8834558b54ee80563b glfwSetInputMode>
 setStickyKeysInputMode :: Window -> StickyKeysInputMode -> IO ()
 setStickyKeysInputMode win sk =
     c'glfwSetInputMode (toC win) c'GLFW_STICKY_KEYS (toC sk)
 
+-- | Gets if sticky mouse buttons are on or not.
+-- See <http://www.glfw.org/docs/3.1/group__input.html#gaa92336e173da9c8834558b54ee80563b glfwSetInputMode>
 getStickyMouseButtonsInputMode :: Window -> IO StickyMouseButtonsInputMode
 getStickyMouseButtonsInputMode win =
     fromC `fmap` c'glfwGetInputMode (toC win) c'GLFW_STICKY_MOUSE_BUTTONS
 
+-- | Sets if sticky mouse buttons should be used or not.
+-- See <http://www.glfw.org/docs/3.1/group__input.html#gaa92336e173da9c8834558b54ee80563b glfwSetInputMode>
 setStickyMouseButtonsInputMode :: Window -> StickyMouseButtonsInputMode -> IO ()
 setStickyMouseButtonsInputMode win smb =
     c'glfwSetInputMode (toC win) c'GLFW_STICKY_MOUSE_BUTTONS (toC smb)
 
 -- end of glfw{GS}etInputMode-related functions
 
+-- | Gets the state of the specified key. If Stickey Keys isn't enabled then it's possible for
+-- keyboard polling to miss individual key presses. Use the callback to avoid this.
+-- See <http://www.glfw.org/docs/3.1/group__input.html#gadd341da06bc8d418b4dc3a3518af9ad2 glfwGetKey>
 getKey :: Window -> Key -> IO KeyState
 getKey win k =
     fromC `fmap` c'glfwGetKey (toC win) (toC k)
 
+-- | Gets the state of a single specified mouse button. If sticky mouse button
+-- mode isn't enabled it's possible for mouse polling to miss individual mouse events. Use
+-- the call back to avoid this.
+-- See <http://www.glfw.org/docs/3.1/group__input.html#gac1473feacb5996c01a7a5a33b5066704 glfwGetMouseButton>
 getMouseButton :: Window -> MouseButton -> IO MouseButtonState
 getMouseButton win b =
     fromC `fmap` c'glfwGetMouseButton (toC win) (toC b)
 
+-- | Returns the position, in screen coodinates, relative to the upper left.
+-- If the 'CursorInputMode' is "disabled", then results are unbounded by the window size.
+-- See <http://www.glfw.org/docs/3.1/group__input.html#ga01d37b6c40133676b9cea60ca1d7c0cc glfwGetCursorPos>
 getCursorPos :: Window -> IO (Double, Double)
 getCursorPos win =
     allocaArray 2 $ \p -> do
@@ -818,6 +998,8 @@
         y <- fromC `fmap` peek p'y
         return (x, y)
 
+-- | Assigns the given callback to use for all keyboard presses and repeats.
+-- See <http://www.glfw.org/docs/3.1/group__input.html#ga7e496507126f35ea72f01b2e6ef6d155 glfwSetKeyCallback>
 setKeyCallback :: Window -> Maybe KeyCallback -> IO ()
 setKeyCallback win = setWindowCallback
     mk'GLFWkeyfun
@@ -827,7 +1009,8 @@
     storedKeyFun
     win
 
-
+-- | Sets the callback to use when the user types a character
+-- See <http://www.glfw.org/docs/3.1/group__input.html#ga556239421c6a5a243c66fca28da9f742 glfwSetCharCallback>
 setCharCallback :: Window -> Maybe CharCallback -> IO ()
 setCharCallback win = setWindowCallback
     mk'GLFWcharfun
@@ -836,6 +1019,8 @@
     storedCharFun
     win
 
+-- | Assigns the callback to run whenver a mouse button is clicked.
+-- See <http://www.glfw.org/docs/3.1/group__input.html#gaef49b72d84d615bca0a6ed65485e035d glfwSetMouseButtonCallback>
 setMouseButtonCallback :: Window -> Maybe MouseButtonCallback -> IO ()
 setMouseButtonCallback win = setWindowCallback
     mk'GLFWmousebuttonfun
@@ -844,6 +1029,8 @@
     storedMouseButtonFun
     win
 
+-- | Assigns the callback to run whenver the cursor position changes.
+-- See <http://www.glfw.org/docs/3.1/group__input.html#ga7dad39486f2c7591af7fb25134a2501d glfwSetCursorPosCallback>
 setCursorPosCallback :: Window -> Maybe CursorPosCallback -> IO ()
 setCursorPosCallback win = setWindowCallback
     mk'GLFWcursorposfun
@@ -852,6 +1039,8 @@
     storedCursorPosFun
     win
 
+-- | Sets the callback for when the cursor enters or leaves the client area.
+-- See <http://www.glfw.org/docs/3.1/input.html#cursor_enter Cursor Enter/Leave Events>
 setCursorEnterCallback :: Window -> Maybe CursorEnterCallback -> IO ()
 setCursorEnterCallback win = setWindowCallback
     mk'GLFWcursorenterfun
@@ -860,6 +1049,8 @@
     storedCursorEnterFun
     win
 
+-- | Sets the callback to run when the user scrolls with the mouse wheel or a touch gesture.
+-- See <http://www.glfw.org/docs/3.1/input.html#scrolling Scroll Input>
 setScrollCallback :: Window -> Maybe ScrollCallback -> IO ()
 setScrollCallback win = setWindowCallback
     mk'GLFWscrollfun
@@ -868,10 +1059,14 @@
     storedScrollFun
     win
 
+-- | Tests if the joystick is present at all
+-- See <http://www.glfw.org/docs/3.1/group__input.html#gaffcbd9ac8ee737fcdd25475123a3c790 glfwJoystickPresent>
 joystickPresent :: Joystick -> IO Bool
 joystickPresent js =
     fromC `fmap` c'glfwJoystickPresent (toC js)
 
+-- | Returns the values of all axes of the specified joystick, normalized to between -1.0 and 1.0
+-- See <http://www.glfw.org/docs/3.1/group__input.html#ga6271d46a5901ec2c99601ccf4dd14731 glfwGetJoystickAxes>
 getJoystickAxes :: Joystick -> IO (Maybe [Double])
 getJoystickAxes js =
     alloca $ \p'n -> do
@@ -881,6 +1076,8 @@
           then return Nothing
           else (Just . map fromC) `fmap` peekArray n p'axes
 
+-- | Returns a list of all joystick button states for the specified joystick.
+-- See <http://www.glfw.org/docs/3.1/group__input.html#gace54cd930dcd502e118fe4021384ce1b glfwGetJoystickButtons>
 getJoystickButtons :: Joystick -> IO (Maybe [JoystickButtonState])
 getJoystickButtons js =
     alloca $ \p'n -> do
@@ -890,6 +1087,8 @@
           then return Nothing
           else (Just . map fromC) `fmap` peekArray n p'buttons
 
+-- | A human-readable name for a Joystick. Not guranteed to be unique.
+-- See <http://www.glfw.org/docs/3.1/group__input.html#gac8d7f6107e05cfd106cfba973ab51e19 glfwGetJoystickName>
 getJoystickName :: Joystick -> IO (Maybe String)
 getJoystickName js = do
     p'name <- c'glfwGetJoystickName (toC js)
@@ -900,6 +1099,10 @@
 --------------------------------------------------------------------------------
 -- Time
 
+-- | Returns the time (in seconds) of the GLFW timer.
+-- This is the amount of time since GLFW was initialized, unless 'setTime' was used.
+-- The exact resolution is system dependent.
+-- See <http://www.glfw.org/docs/3.1/group__input.html#gaa6cf4e7a77158a3b8fd00328b1720a4a glfwGetTime>
 getTime :: IO (Maybe Double)
 getTime = do
     t <- fromC `fmap` c'glfwGetTime
@@ -907,6 +1110,10 @@
       then Nothing
       else Just t
 
+-- | Sets the GLFW timer to the specified value, which is measured in seconds, and must be positive.
+-- The value must also be less than ~584 years in seconds (18446744073.0).
+-- After this the timer begins to count upward at the normal rate.
+-- See <http://www.glfw.org/docs/3.1/group__input.html#gaf59589ef6e8b8c8b5ad184b25afd4dc0 glfwSetTime>
 setTime :: Double -> IO ()
 setTime =
     c'glfwSetTime . toC
@@ -914,10 +1121,16 @@
 --------------------------------------------------------------------------------
 -- Context
 
+-- | Makes the context of the specified window the current one for the calling thread.
+-- A context can only be made current on a single thread at a time,
+-- and each thread can have only a single current context at a time.
+-- See <http://www.glfw.org/docs/3.1/group__context.html#ga1c04dc242268f827290fe40aa1c91157 glfwMakeContextCurrent>
 makeContextCurrent :: Maybe Window -> IO ()
 makeContextCurrent =
     c'glfwMakeContextCurrent . maybe nullPtr toC
 
+-- | Obtains which window owns the current context of the calling thread.
+-- See <http://www.glfw.org/docs/3.1/group__context.html#gac84759b1f6c2d271a4fea8ae89ec980d glfwGetCurrentContext>
 getCurrentContext :: IO (Maybe Window)
 getCurrentContext = do
     p'win <- c'glfwGetCurrentContext
@@ -925,14 +1138,22 @@
       then Nothing
       else Just $ fromC p'win
 
+-- | Swaps the front and back buffers of the window.
+-- See <http://www.glfw.org/docs/3.1/group__window.html#ga15a5a1ee5b3c2ca6b15ca209a12efd14 glfwSwapBuffers>
 swapBuffers :: Window -> IO ()
 swapBuffers =
     c'glfwSwapBuffers . toC
 
+-- | Sets the number of screen updates that the GPU should wait after 'swapBuffers' before actually swapping the buffers.
+-- Generates 'Error'NoCurrentContext' if no context is current.
+-- See <http://www.glfw.org/docs/3.1/group__context.html#ga6d4e0cdf151b5e579bd67f13202994ed glfwSwapInterval>
 swapInterval :: Int -> IO ()
 swapInterval =
     c'glfwSwapInterval . toC
 
+-- | If the current OpenGL or OpenGL ES context supports the extension specified.
+-- Generates 'Error'NoCurrentContext' if no context is current.
+-- See <http://www.glfw.org/docs/3.1/group__context.html#ga87425065c011cef1ebd6aac75e059dfa glfwExtensionSupported>
 extensionSupported :: String -> IO Bool
 extensionSupported ext =
     withCString ext $ \p'ext ->
@@ -940,11 +1161,17 @@
 
 --------------------------------------------------------------------------------
 -- Clipboard
+-- http://www.glfw.org/docs/3.1/input.html#clipboard
 
+-- | The window that will own the clipboard contents, and also the clipboard string.
+-- See <http://www.glfw.org/docs/3.1/group__input.html#gaba1f022c5eb07dfac421df34cdcd31dd glfwSetClipboardString>
 setClipboardString :: Window -> String -> IO ()
 setClipboardString win s =
     withCString s (c'glfwSetClipboardString (toC win))
 
+-- | Obtains the contents of the system keyboard, if possible.
+-- Generates 'Error'FormatUnavailable' if the system clipboard is empty or if it's not a UTF-8 string.
+-- See <http://www.glfw.org/docs/3.1/group__input.html#ga5aba1d704d9ab539282b1fbe9f18bb94 glfwGetClipboardString>
 getClipboardString :: Window -> IO (Maybe String)
 getClipboardString win = do
     p's <- c'glfwGetClipboardString (toC win)
@@ -957,7 +1184,7 @@
 --------------------------------------------------------------------------------
 
 -- Cursor Objects
--- http://www.glfw.org/docs/latest/input.html#cursor_object
+-- http://www.glfw.org/docs/3.1/input.html#cursor_object
 
 -- | Creates a new cursor.
 createCursor :: Image -- ^ The desired cursor image.
@@ -973,12 +1200,12 @@
                               (toC h)
                               p'pxs
         poke p'img img
-        Cursor <$> c'glfwCreateCursor p'img (toC x) (toC y)
+        Cursor `fmap` c'glfwCreateCursor p'img (toC x) (toC y)
 
 -- | Creates a cursor with a standard shape that can be set for a window with
 -- setCursor.
 createStandardCursor :: StandardCursorShape -> IO Cursor
-createStandardCursor = (Cursor <$>) . c'glfwCreateStandardCursor . toC
+createStandardCursor = (fmap Cursor) . c'glfwCreateStandardCursor . toC
 
 -- | Sets the cursor image to be used when the cursor is over the client area
 -- of the specified window. The set cursor will only be visible when the cursor
@@ -994,9 +1221,7 @@
 destroyCursor :: Cursor -> IO ()
 destroyCursor = c'glfwDestroyCursor . unCursor
 
--- Path Drop Input
--- http://www.glfw.org/docs/latest/input.html#path_drop
-
+-- | A callback that allows for drag and drop support.
 type DropCallback = Window    -- ^ The window that received the event.
                   -> [String] -- ^ The file and/or directory path names
                   -> IO ()
diff --git a/Graphics/UI/GLFW/Types.hs b/Graphics/UI/GLFW/Types.hs
--- a/Graphics/UI/GLFW/Types.hs
+++ b/Graphics/UI/GLFW/Types.hs
@@ -3,10 +3,13 @@
 {-# LANGUAGE StandaloneDeriving #-}
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 
+-- | The types of the package. This module is considered "internal", and the
+-- types are re-exported from Graphics.UI.GLFW as necessary.
 module Graphics.UI.GLFW.Types where
 
 --------------------------------------------------------------------------------
 
+import Control.DeepSeq  (NFData)
 import Data.Data        (Data)
 import Data.IORef       (IORef)
 import Data.Typeable    (Typeable)
@@ -19,39 +22,52 @@
 --------------------------------------------------------------------------------
 -- Error handling
 
+-- | An enum for one of the <http://www.glfw.org/docs/3.1/group__errors.html#ga196e125ef261d94184e2b55c05762f14 GLFW error codes>.
 data Error =
-    Error'NotInitialized
-  | Error'NoCurrentContext
-  | Error'InvalidEnum
-  | Error'InvalidValue
-  | Error'OutOfMemory
-  | Error'ApiUnavailable
-  | Error'VersionUnavailable
-  | Error'PlatformError
-  | Error'FormatUnavailable
+    Error'NotInitialized -- ^ <http://www.glfw.org/docs/3.1/group__errors.html#ga2374ee02c177f12e1fa76ff3ed15e14a doc>
+  | Error'NoCurrentContext -- ^ <http://www.glfw.org/docs/3.1/group__errors.html#gaa8290386e9528ccb9e42a3a4e16fc0d0 doc>
+  | Error'InvalidEnum -- ^ <http://www.glfw.org/docs/3.1/group__errors.html#ga76f6bb9c4eea73db675f096b404593ce doc>
+  | Error'InvalidValue -- ^ <http://www.glfw.org/docs/3.1/group__errors.html#gaaf2ef9aa8202c2b82ac2d921e554c687 doc>
+  | Error'OutOfMemory -- ^ <http://www.glfw.org/docs/3.1/group__errors.html#ga9023953a2bcb98c2906afd071d21ee7f doc>
+  | Error'ApiUnavailable -- ^ <http://www.glfw.org/docs/3.1/group__errors.html#ga56882b290db23261cc6c053c40c2d08e doc>
+  | Error'VersionUnavailable -- ^ <http://www.glfw.org/docs/3.1/group__errors.html#gad16c5565b4a69f9c2a9ac2c0dbc89462 doc>
+  | Error'PlatformError -- ^ <http://www.glfw.org/docs/3.1/group__errors.html#gad44162d78100ea5e87cdd38426b8c7a1 doc>
+  | Error'FormatUnavailable -- ^ <http://www.glfw.org/docs/3.1/group__errors.html#ga196e125ef261d94184e2b55c05762f14 doc>
   deriving (Data, Enum, Eq, Ord, Read, Show, Typeable, Generic)
 
+instance NFData Error
+
 --------------------------------------------------------------------------------
 -- Initialization and version information
 
+-- | The library version of the GLFW implementation in use.
+-- See <http://www.glfw.org/docs/3.1/intro.html#intro_version Version Management>
 data Version = Version
   { versionMajor    :: Int
   , versionMinor    :: Int
   , versionRevision :: Int
   } deriving (Data, Eq, Ord, Read, Show, Typeable, Generic)
 
+instance NFData Version
+
 --------------------------------------------------------------------------------
 -- Monitor handling
 
+-- | Represents a physical monitor that's currently connected.
+-- See the <http://www.glfw.org/docs/3.1/monitor.html Monitor Guide>
 newtype Monitor = Monitor
   { unMonitor :: Ptr C'GLFWmonitor
   } deriving (Data, Eq, Ord, Show, Typeable, Generic)
 
+-- | Part of the 'MonitorCallback', for when a monitor gets connected or disconnected.
 data MonitorState =
     MonitorState'Connected
   | MonitorState'Disconnected
   deriving (Data, Eq, Ord, Read, Show, Typeable, Generic)
 
+instance NFData MonitorState
+
+-- | See <http://www.glfw.org/docs/3.1/monitor.html#monitor_modes Video Modes>
 data VideoMode = VideoMode
   { videoModeWidth       :: Int
   , videoModeHeight      :: Int
@@ -61,15 +77,21 @@
   , videoModeRefreshRate :: Int
   } deriving (Data, Eq, Ord, Read, Show, Typeable, Generic)
 
--- It would be bad to give clients a way to construct invalid gamma ramps with
--- lists of unequal length, so this constructor should not be exported.
+instance NFData VideoMode
+
+-- | Lets you adjust the gamma of a monitor. To ensure that only valid values are created, use 'makeGammaRamp'.
+-- See <http://www.glfw.org/docs/3.1/monitor.html#monitor_gamma Gamma Ramp>.
 data GammaRamp = GammaRamp
+  -- NOTE: It would be bad to give clients a way to construct invalid gamma ramps
+  -- with lists of unequal length, so this constructor should not be exported.
   { gammaRampRed   :: [Int]
   , gammaRampGreen :: [Int]
   , gammaRampBlue  :: [Int]
   } deriving (Data, Eq, Ord, Read, Show, Typeable, Generic)
 
--- Smart constructor for GammaRamp.
+instance NFData GammaRamp
+
+-- | Smart constructor for a 'GammaRamp'.
 makeGammaRamp :: [Int] -> [Int] -> [Int] -> Maybe GammaRamp
 makeGammaRamp rs gs bs
     | lengthsEqual = Just $ GammaRamp rs gs bs
@@ -84,6 +106,7 @@
 --------------------------------------------------------------------------------
 -- Window handling
 
+-- | Collects all the callbacks that can be associated with a Window into a single place.
 data WindowCallbacks = WindowCallbacks
   { storedCharFun             :: IORef C'GLFWcharfun
   , storedCursorEnterFun      :: IORef C'GLFWcursorenterfun
@@ -101,10 +124,15 @@
   , storedDropFun             :: IORef C'GLFWdropfun
   }
 
+-- | Reprisents a GLFW window value.
+-- See the <http://www.glfw.org/docs/3.1/window.html Window Guide>
 newtype Window = Window
   { unWindow :: Ptr C'GLFWwindow
   } deriving (Data, Eq, Ord, Show, Typeable, Generic)
 
+-- | Lets you set various window hints before creating a 'Window'.
+-- See <http://www.glfw.org/docs/3.1/window.html#window_hints Window Hints>,
+-- particularly <http://www.glfw.org/docs/3.1/window.html#window_hints_values Supported and Default Values>.
 data WindowHint =
     WindowHint'Resizable           Bool
   | WindowHint'Visible             Bool
@@ -133,36 +161,54 @@
   | WindowHint'OpenGLProfile       OpenGLProfile
   deriving (Data, Eq, Ord, Read, Show, Typeable, Generic)
 
+instance NFData WindowHint
+
+-- | For use with the focus callback.
 data FocusState =
     FocusState'Focused
   | FocusState'Defocused
   deriving (Data, Enum, Eq, Ord, Read, Show, Typeable, Generic)
 
+instance NFData FocusState
+
+-- | For use with the iconify callback. (note: iconified means minimized)
 data IconifyState =
     IconifyState'Iconified
   | IconifyState'NotIconified
   deriving (Data, Enum, Eq, Ord, Read, Show, Typeable, Generic)
 
+instance NFData IconifyState
+
+-- | The OpenGL robustness strategy.
 data ContextRobustness =
     ContextRobustness'NoRobustness
   | ContextRobustness'NoResetNotification
   | ContextRobustness'LoseContextOnReset
   deriving (Data, Enum, Eq, Ord, Read, Show, Typeable, Generic)
 
+instance NFData ContextRobustness
+
+-- | The OpenGL profile.
 data OpenGLProfile =
     OpenGLProfile'Any
   | OpenGLProfile'Compat
   | OpenGLProfile'Core
   deriving (Data, Enum, Eq, Ord, Read, Show, Typeable, Generic)
 
+instance NFData OpenGLProfile
+
+-- | The type of OpenGL to create a context for.
 data ClientAPI =
     ClientAPI'OpenGL
   | ClientAPI'OpenGLES
   deriving (Data, Enum, Eq, Ord, Read, Show, Typeable, Generic)
 
+instance NFData ClientAPI
+
 --------------------------------------------------------------------------------
 -- Input handling
 
+-- | Part of the <http://www.glfw.org/docs/3.1/input.html#input_keyboard Keyboard Input> system.
 data Key =
     Key'Unknown
   | Key'Space
@@ -287,12 +333,18 @@
   | Key'Menu
   deriving (Data, Enum, Eq, Ord, Read, Show, Typeable, Generic)
 
+instance NFData Key
+
+-- | The state of an individual key when 'getKey' is called.
 data KeyState =
     KeyState'Pressed
   | KeyState'Released
   | KeyState'Repeating
   deriving (Data, Enum, Eq, Ord, Read, Show, Typeable, Generic)
 
+instance NFData KeyState
+
+-- | For use with the <http://www.glfw.org/docs/3.1/input.html#joystick Joystick Input> system.
 data Joystick =
     Joystick'1
   | Joystick'2
@@ -312,11 +364,17 @@
   | Joystick'16
   deriving (Data, Enum, Eq, Ord, Read, Show, Typeable, Generic)
 
+instance NFData Joystick
+
+-- | If a given joystick button is pressed or not when 'getJoystickButtons' is called.
 data JoystickButtonState =
     JoystickButtonState'Pressed
   | JoystickButtonState'Released
   deriving (Data, Enum, Eq, Ord, Read, Show, Typeable, Generic)
 
+instance NFData JoystickButtonState
+
+-- | Part of the <http://www.glfw.org/docs/3.1/input.html#input_mouse Mouse Input> system.
 data MouseButton =
     MouseButton'1
   | MouseButton'2
@@ -328,32 +386,56 @@
   | MouseButton'8
   deriving (Data, Enum, Eq, Ord, Read, Show, Typeable, Generic)
 
+instance NFData MouseButton
+
+-- | If the mouse button is pressed or not when 'getMouseButton' is called.
 data MouseButtonState =
     MouseButtonState'Pressed
   | MouseButtonState'Released
   deriving (Data, Enum, Eq, Ord, Read, Show, Typeable, Generic)
 
+instance NFData MouseButtonState
+
+-- | If the mouse's cursor is in the window or not.
 data CursorState =
     CursorState'InWindow
   | CursorState'NotInWindow
   deriving (Data, Enum, Eq, Ord, Read, Show, Typeable, Generic)
 
+instance NFData CursorState
+
+-- | Allows for special forms of mouse input.
+-- See <http://www.glfw.org/docs/3.1/input.html#cursor_mode Cursor Modes>
 data CursorInputMode =
     CursorInputMode'Normal
   | CursorInputMode'Hidden
   | CursorInputMode'Disabled
   deriving (Data, Enum, Eq, Ord, Read, Show, Typeable, Generic)
 
+instance NFData CursorInputMode
+
+-- | When sticky keys is enabled, once a key is pressed it will remain pressed
+-- at least until the state is polled with 'getKey'. After that, if the key has
+-- been released it will switch back to released. This helps prevent problems
+-- with low-resolution polling missing key pressed. Note that use of the
+-- callbacks to avoid this problem the the recommended route, and this is just
+-- for a fallback.
 data StickyKeysInputMode =
     StickyKeysInputMode'Enabled
   | StickyKeysInputMode'Disabled
   deriving (Data, Enum, Eq, Ord, Read, Show, Typeable, Generic)
 
+instance NFData StickyKeysInputMode
+
+-- | This is the mouse version of "StickyKeysInputMode".
 data StickyMouseButtonsInputMode =
     StickyMouseButtonsInputMode'Enabled
   | StickyMouseButtonsInputMode'Disabled
   deriving (Data, Enum, Eq, Ord, Read, Show, Typeable, Generic)
 
+instance NFData StickyMouseButtonsInputMode
+
+-- | Modifier keys that were pressed as part of another keypress event.
 data ModifierKeys = ModifierKeys
   { modifierKeysShift   :: Bool
   , modifierKeysControl :: Bool
@@ -361,22 +443,31 @@
   , modifierKeysSuper   :: Bool
   } deriving (Data, Eq, Ord, Read, Show, Typeable, Generic)
 
+instance NFData ModifierKeys
+
 --------------------------------------------------------------------------------
 -- 3.1 Additions
 --------------------------------------------------------------------------------
 
 deriving instance Data CUChar
 
+-- | GLFW image data, for setting up custom mouse cursor appearnaces.
 data Image = Image
   { imageWidth  :: Int
   , imageHeight :: Int
   , imagePixels :: [CUChar]
   } deriving (Data, Eq, Ord, Read, Show, Typeable, Generic)
 
+instance NFData Image
+
+-- | Reprisents a GLFW cursor.
 newtype Cursor = Cursor
   { unCursor :: Ptr C'GLFWcursor
   } deriving (Data, Eq, Ord, Show, Typeable, Generic)
 
+-- | Lets you use one of the standard cursor appearnaces that the local
+-- system theme provides for.
+-- See <http://www.glfw.org/docs/3.1/input.html#cursor_standard Standard Cursor Creation>.
 data StandardCursorShape =
     StandardCursorShape'Arrow
   | StandardCursorShape'IBeam
@@ -385,6 +476,8 @@
   | StandardCursorShape'HResize
   | StandardCursorShape'VResize
   deriving (Data, Enum, Eq, Ord, Read, Show, Typeable, Generic)
+
+instance NFData StandardCursorShape
 
 --------------------------------------------------------------------------------
 
