diff --git a/changelog b/changelog
--- a/changelog
+++ b/changelog
@@ -1,14 +1,23 @@
+2014-03-10 0.2.1
+=================
+
+    * Add Decoding/Encoding sections
+    * Make the examples runnable by doctest
+    * Fix hlint warnings
+    * Add 'secondsSinceEpoch' to extract the seconds from epoch from an IntDate
+
+
 2014-03-10 0.2.0
 =================
 
 	* Export the IntDate and StringOrURI types #5a1137b
 
-2014-03-03	0.1.1
+2014-03-03  0.1.1
 =================
 
 	* Verify that invalid input to the decode* functions fails as expected
 
-2014-03-03	0.1.0
+2014-03-03  0.1.0
 =================
 
 	* Initial release
diff --git a/jwt.cabal b/jwt.cabal
--- a/jwt.cabal
+++ b/jwt.cabal
@@ -2,7 +2,7 @@
 -- documentation, see http://haskell.org/cabal/users-guide/
 
 name:                jwt
-version:             0.2.0
+version:             0.2.1
 synopsis:            JSON Web Token (JWT) decoding and encoding
 license:             MIT
 license-file:        LICENSE
diff --git a/src/Web/JWT.hs b/src/Web/JWT.hs
--- a/src/Web/JWT.hs
+++ b/src/Web/JWT.hs
@@ -27,8 +27,10 @@
 module Web.JWT
     (
     -- * Encoding & Decoding JWTs
+    -- ** Decoding
       decode
     , decodeAndVerifySignature
+    -- ** Encoding
     , encodeSigned
     , encodeUnsigned
 
@@ -43,6 +45,7 @@
     -- ** JWT claims set
     , intDate
     , stringOrURI
+    , secondsSinceEpoch
     -- ** JWT header
     , typ
     , cty
@@ -122,9 +125,12 @@
 signature (Verified _ _ s) = Just s
 
 -- | A JSON numeric value representing the number of seconds from
---   1970-01-01T0:0:0Z UTC until the specified UTC date/time.
+-- 1970-01-01T0:0:0Z UTC until the specified UTC date/time.
 newtype IntDate = IntDate Integer deriving (Show, Eq)
 
+-- | Return the seconds since 1970-01-01T0:0:0Z UTC for the given 'IntDate'
+secondsSinceEpoch :: IntDate -> NominalDiffTime
+secondsSinceEpoch (IntDate s) = fromInteger s
 
 -- | A JSON string value, with the additional requirement that while
 -- arbitrary string values MAY be used, any value containing a ":"
@@ -197,23 +203,20 @@
     def = JWTClaimsSet Nothing Nothing Nothing Nothing Nothing Nothing Nothing Map.empty
 
 
+
+
 -- | Encode a claims set using the given secret
 --
--- > {-# LANGUAGE OverloadedStrings #-}
--- > import           Data.Aeson
--- > import qualified Data.Map as Map
--- >
--- > let cs = def {  -- def returns a default JWTClaimsSet
--- >     iss = stringOrURI "Foo"
--- >   , unregisteredClaims = Map.fromList [("http://example.com/is_root", (Bool True))]
--- > }
--- >     key = secret "secret-key"
--- >     jwt = encodeSigned HS256 key cs
---
--- This yields:
---
--- > >>> jwt
--- > "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJodHRwOi8vZXhhbXBsZS5jb20vaXNfcm9vdCI6dHJ1ZSwiaXNzIjoiRm9vIn0.vHQHuG3ujbnBUmEp-fSUtYxk27rLiP2hrNhxpyWhb2E"
+-- >>> :{
+--  let
+--      cs = def { -- def returns a default JWTClaimsSet
+--         iss = stringOrURI "Foo"
+--       , unregisteredClaims = Map.fromList [("http://example.com/is_root", (Bool True))]
+--      }
+--      key = secret "secret-key"
+--  in encodeSigned HS256 key cs
+-- :}
+-- "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJodHRwOi8vZXhhbXBsZS5jb20vaXNfcm9vdCI6dHJ1ZSwiaXNzIjoiRm9vIn0.vHQHuG3ujbnBUmEp-fSUtYxk27rLiP2hrNhxpyWhb2E"
 encodeSigned :: Algorithm -> Secret -> JWTClaimsSet -> JSON
 encodeSigned algo secret claims = dotted [header, claim, signature]
     where claim     = encodeJWT claims
@@ -225,20 +228,16 @@
 
 -- | Encode a claims set without signing it
 --
--- > {-# LANGUAGE OverloadedStrings #-}
--- > import           Data.Aeson
--- > import qualified Data.Map as Map
--- >
--- > let cs = def {  -- def returns a default JWTClaimsSet
--- >     iss = stringOrURI "Foo"
--- >   , unregisteredClaims = Map.fromList [("http://example.com/is_root", (Bool True))]
--- > }
--- >     jwt = encodeUnsigned cs
---
--- This yields:
---
--- > >>> jwt
--- > "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJodHRwOi8vZXhhbXBsZS5jb20vaXNfcm9vdCI6dHJ1ZSwiaXNzIjoiRm9vIn0."
+-- >>> :{
+--  let
+--      cs = def { -- def returns a default JWTClaimsSet
+--      iss = stringOrURI "Foo"
+--    , iat = intDate 1394700934
+--    , unregisteredClaims = Map.fromList [("http://example.com/is_root", (Bool True))]
+--  }
+--  in encodeUnsigned cs
+-- :}
+-- "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjEzOTQ3MDA5MzQsImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlLCJpc3MiOiJGb28ifQ."
 encodeUnsigned :: JWTClaimsSet -> JSON
 encodeUnsigned claims = dotted [header, claim, ""]
     where claim     = encodeJWT claims
@@ -253,29 +252,23 @@
 -- (e.g. the secret needs to be retrieved based on unverified information
 -- from the claims set).
 --
--- > import qualified Data.Text as T
--- > let input = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzb21lIjoicGF5bG9hZCJ9.Joh1R2dYzkRvDkqv3sygm5YyK8Gi4ShZqbhK2gxcs2U" :: T.Text
--- >     mJwt = decode input
--- >     mHeader = fmap header mJwt
--- >     mClaims = fmap claims mJwt
--- >     mSignature = join $ fmap signature mJwt
---
--- This yields:
---
--- > >>> mHeader
--- > Just (JWTHeader {typ = Just "JWT", cty = Nothing, alg = Just HS256})
---
--- and
---
--- > >>> mClaims
--- > Just (JWTClaimsSet {iss = Nothing, sub = Nothing, aud = Nothing,
--- >     exp = Nothing, nbf = Nothing, iat = Nothing, jti = Nothing,
--- >     unregisteredClaims = fromList [("some",String "payload")]})
+-- >>> :{
+--  let
+--      input = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzb21lIjoicGF5bG9hZCJ9.Joh1R2dYzkRvDkqv3sygm5YyK8Gi4ShZqbhK2gxcs2U" :: T.Text
+--      mJwt = decode input
+--  in fmap header mJwt
+-- :}
+-- Just (JWTHeader {typ = Just "JWT", cty = Nothing, alg = Just HS256})
 --
 -- and
 --
--- > >>> mSignature
--- > Nothing
+-- >>> :{
+--  let
+--      input = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzb21lIjoicGF5bG9hZCJ9.Joh1R2dYzkRvDkqv3sygm5YyK8Gi4ShZqbhK2gxcs2U" :: T.Text
+--      mJwt = decode input
+--  in fmap claims mJwt
+-- :}
+-- Just (JWTClaimsSet {iss = Nothing, sub = Nothing, aud = Nothing, exp = Nothing, nbf = Nothing, iat = Nothing, jti = Nothing, unregisteredClaims = fromList [("some",String "payload")]})
 decode :: JSON -> Maybe (JWT UnverifiedJWT)
 decode input = do
     (h,c) <- extractElems $ T.splitOn "." input
@@ -293,24 +286,13 @@
 -- This will return a VerifiedJWT if and only if the signature can be verified
 -- using the given secret.
 --
--- > import qualified Data.Text as T
--- > let input = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzb21lIjoicGF5bG9hZCJ9.Joh1R2dYzkRvDkqv3sygm5YyK8Gi4ShZqbhK2gxcs2U" :: T.Text
--- >     mJwt = decodeAndVerifySignature (secret "secret") input
--- >     mSignature = join $ fmap signature mJwt
---
--- This yields:
---
--- > >>> mJwt
--- > Just (Verified (JWTHeader {typ = Just "JWT", cty = Nothing, alg = Just HS256})
--- >    (JWTClaimsSet {iss = Nothing, sub = Nothing, aud = Nothing, exp = Nothing,
--- >     nbf = Nothing, iat = Nothing, jti = Nothing,
--- >     unregisteredClaims = fromList [("some",String "payload")]})
--- >    (Signature "Joh1R2dYzkRvDkqv3sygm5YyK8Gi4ShZqbhK2gxcs2U"))
---
--- and
---
--- > >>> mSignature
--- > Just (Signature "Joh1R2dYzkRvDkqv3sygm5YyK8Gi4ShZqbhK2gxcs2U")
+-- >>> :{
+--  let
+--      input = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzb21lIjoicGF5bG9hZCJ9.Joh1R2dYzkRvDkqv3sygm5YyK8Gi4ShZqbhK2gxcs2U" :: T.Text
+--      mJwt = decodeAndVerifySignature (secret "secret") input
+--  in join $ fmap signature mJwt
+-- :}
+-- Just (Signature "Joh1R2dYzkRvDkqv3sygm5YyK8Gi4ShZqbhK2gxcs2U")
 decodeAndVerifySignature :: Secret -> T.Text -> Maybe (JWT VerifiedJWT)
 decodeAndVerifySignature secret' input = do
         (h,c,s) <- extractElems $ T.splitOn "." input
@@ -347,7 +329,7 @@
 -- String cannot be converted (e.g. if the String contains a ':' but is
 -- *not* a valid URI).
 stringOrURI :: T.Text -> Maybe  StringOrURI
-stringOrURI t | URI.isURI $ T.unpack t = U <$> (URI.parseURI $ T.unpack t)
+stringOrURI t | URI.isURI $ T.unpack t = U <$> URI.parseURI (T.unpack t)
 stringOrURI t = Just (S t)
 
 -- =================================================================================
diff --git a/tests/src/Web/Base64Tests.hs b/tests/src/Web/Base64Tests.hs
--- a/tests/src/Web/Base64Tests.hs
+++ b/tests/src/Web/Base64Tests.hs
@@ -38,7 +38,7 @@
 
 case_base64EncodeDecodeStringNoPadding = do
     let header = "sdjkfhaks jdhfak sjldhfa lkjsdf"
-    header @=? (base64Decode $ base64Encode header)
+    header @=? base64Decode (base64Encode header)
 
 case_base64DecodeString = do
     let str = "eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJIUzI1NiJ9"
@@ -46,7 +46,7 @@
 
 prop_base64_encode_decode = f
     where f :: T.Text -> Bool
-          f input = (base64Decode $ base64Encode input) == input
+          f input = base64Decode (base64Encode input) == input
 
 
 instance Arbitrary T.Text where
diff --git a/tests/src/Web/JWTTests.hs b/tests/src/Web/JWTTests.hs
--- a/tests/src/Web/JWTTests.hs
+++ b/tests/src/Web/JWTTests.hs
@@ -16,11 +16,11 @@
 import qualified Data.Text             as T
 import qualified Data.Text.Lazy        as TL
 import           Data.Aeson.Types
-import qualified Data.Aeson            as JSON
 import           Data.Maybe
 import           Data.String (fromString, IsString)
 import           Data.Time
 
+
 import           Web.JWT
 
 defaultTestGroup :: TestTree
@@ -34,22 +34,22 @@
 case_stringOrURIString = do
     let str = "foo bar baz 2312j!@&^#^*!(*@"
         sou = stringOrURI str
-    (Just str) @=? (fmap (T.pack . show) sou)
+    Just str @=? fmap (T.pack . show) sou
 
 case_stringOrURI= do
     let str = "http://user@example.com:8900/foo/bar?baz=t;"
         sou = stringOrURI str
-    (Just str) @=? (fmap (T.pack . show) sou)
+    Just str @=? fmap (T.pack . show) sou
 
 case_decodeJWT = do
     -- Generated with ruby-jwt
     let input = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzb21lIjoicGF5bG9hZCJ9.Joh1R2dYzkRvDkqv3sygm5YyK8Gi4ShZqbhK2gxcs2U"
         mJwt = decode input
     True @=? isJust mJwt
-    True @=? (isJust $ fmap signature mJwt)
+    True @=? isJust (fmap signature mJwt)
     let (Just unverified) = mJwt
-    (Just HS256) @=? (alg $ header unverified)
-    (Just "payload") @=? (Map.lookup "some" $ unregisteredClaims $ claims unverified)
+    Just HS256 @=? alg (header unverified)
+    Just "payload" @=? Map.lookup "some" (unregisteredClaims $ claims unverified)
 
 case_decodeAndVerifyJWT = do
     -- Generated with ruby-jwt
@@ -57,8 +57,8 @@
         mJwt = decodeAndVerifySignature (secret "secret") input
     True @=? isJust mJwt
     let (Just verified) = mJwt
-    (Just HS256) @=? (alg $ header verified)
-    (Just "payload") @=? (Map.lookup "some" $ unregisteredClaims $ claims verified)
+    Just HS256 @=? alg (header verified)
+    Just "payload" @=? Map.lookup "some" (unregisteredClaims $ claims verified)
 
 case_decodeAndVerifyJWTFailing = do
     -- Generated with ruby-jwt, modified to be invalid
@@ -69,17 +69,17 @@
 case_decodeInvalidInput = do
     let inputs = ["", "a.", "a.b"]
         result = map decode inputs
-    True @=? (all isNothing result)
+    True @=? all isNothing result
 
 case_decodeAndVerifySignatureInvalidInput = do
     let inputs = ["", "a.", "a.b"]
         result = map (decodeAndVerifySignature (secret "secret")) inputs
-    True @=? (all isNothing result)
+    True @=? all isNothing result
 
 case_encodeJWTNoMac = do
     let cs = def {
         iss = stringOrURI "Foo"
-      , unregisteredClaims = Map.fromList [("http://example.com/is_root", (Bool True))]
+      , unregisteredClaims = Map.fromList [("http://example.com/is_root", Bool True)]
     }
         jwt = encodeUnsigned cs
     -- Verified using https://py-jwt-decoder.appspot.com/
@@ -88,29 +88,31 @@
 case_encodeDecodeJWTNoMac = do
     let cs = def {
         iss = stringOrURI "Foo"
-      , unregisteredClaims = Map.fromList [("http://example.com/is_root", (Bool True))]
+      , unregisteredClaims = Map.fromList [("http://example.com/is_root", Bool True)]
     }
         mJwt = decode $ encodeUnsigned cs
-    True @=? (isJust mJwt)
+    True @=? isJust mJwt
     let (Just unverified) = mJwt
     cs @=? claims unverified
 
 case_encodeDecodeJWT = do
-    let cs = def {
+    let now = 1394573404
+        cs = def {
         iss = stringOrURI "Foo"
-      , unregisteredClaims = Map.fromList [("http://example.com/is_root", (Bool True))]
+      , iat = intDate now
+      , unregisteredClaims = Map.fromList [("http://example.com/is_root", Bool True)]
     }
         key = secret "secret-key"
         mJwt = decode $ encodeSigned HS256 key cs
-    True @=? (isJust mJwt)
     let (Just unverified) = mJwt
     cs @=? claims unverified
+    Just now @=? fmap secondsSinceEpoch (iat (claims unverified))
 
 case_tokenIssuer = do
     let iss' = stringOrURI "Foo"
         cs = def {
         iss = iss'
-      , unregisteredClaims = Map.fromList [("http://example.com/is_root", (Bool True))]
+      , unregisteredClaims = Map.fromList [("http://example.com/is_root", Bool True)]
     }
         key = secret "secret-key"
         t   = encodeSigned HS256 key cs
@@ -129,7 +131,7 @@
         cs = def {
         iss = stringOrURI "Foo"
       , iat = intDate now
-      , unregisteredClaims = Map.fromList [("http://example.com/is_root", (Bool True))]
+      , unregisteredClaims = Map.fromList [("http://example.com/is_root", Bool True)]
     }
     -- The expected string can be decoded using the ruby-jwt library
     "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjEyMzQsImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlLCJpc3MiOiJGb28ifQ.F3VCSxBBnY2caX4AH4GvIHyTVUhOnJF9Av_G_N4m710" @=? encodeSigned HS256 (secret "secret") cs
@@ -138,7 +140,7 @@
 prop_stringOrURIProp = f
     where f :: StringOrURI -> Bool
           f sou = let s = stringOrURI $ T.pack $ show sou
-                  in (Just sou) == s
+                  in Just sou == s
 
 prop_encode_decode_prop = f
     where f :: JWTClaimsSet -> Bool
@@ -168,7 +170,7 @@
 
 instance Arbitrary IntDate where
     arbitrary = fmap (f . intDate) (arbitrary :: QC.Gen NominalDiffTime)
-        where f mIntDate = fromMaybe (fromJust $ intDate 1) mIntDate
+        where f = fromMaybe (fromJust $ intDate 1)
 
 instance Arbitrary NominalDiffTime where
     arbitrary = arbitrarySizedFractional
@@ -177,7 +179,7 @@
 instance Arbitrary StringOrURI where
     arbitrary = fmap (f . stringOrURI) (arbitrary :: QC.Gen T.Text)
         where
-            f mSou = fromMaybe (fromJust $ stringOrURI "http://example.com") mSou
+            f = fromMaybe (fromJust $ stringOrURI "http://example.com")
 
 instance Arbitrary T.Text where
     arbitrary = fromString <$> (arbitrary :: QC.Gen String)
