diff --git a/Network/Wreq.hs b/Network/Wreq.hs
--- a/Network/Wreq.hs
+++ b/Network/Wreq.hs
@@ -678,6 +678,10 @@
 -- The \"magical\" type conversion on the right-hand side of ':='
 -- above is due to the 'FormValue' class. This package provides
 -- sensible instances for the standard string and number types.
+-- You may need to explicitly add types to the values (e.g. :: String)
+-- in order to evade ambigous type errors.
+--
+-- >>> r <- post "http://httpbin.org/post" ["num" := (31337 :: Int), "str" := ("foo" :: String)]
 --
 -- The 'Aeson.Value' type gives a JSON request body with a
 -- @Content-Type@ of @application/json@. Any instance of
diff --git a/Network/Wreq/Internal/AWS.hs b/Network/Wreq/Internal/AWS.hs
--- a/Network/Wreq/Internal/AWS.hs
+++ b/Network/Wreq/Internal/AWS.hs
@@ -8,9 +8,9 @@
 
 import Control.Applicative ((<$>))
 import Control.Lens ((%~), (^.), (&), to)
-import Crypto.MAC (hmac, hmacGetDigest)
+import Crypto.MAC.HMAC (HMAC (..), hmac, hmacGetDigest)
 import Data.ByteString.Base16 as HEX (encode)
-import Data.Byteable (toBytes)
+import Data.ByteArray (convert)
 import Data.Char (toLower)
 import Data.List (sort)
 import Data.Monoid ((<>))
@@ -21,9 +21,9 @@
 import Network.HTTP.Types (parseSimpleQuery, urlEncode)
 import Network.Wreq.Internal.Lens
 import Network.Wreq.Internal.Types (AWSAuthVersion(..))
-import qualified Crypto.Hash as CT (HMAC, SHA256)
-import qualified Crypto.Hash.SHA256 as SHA256 (hash, hashlazy)
+import qualified Crypto.Hash as CT (Digest, SHA256, hash, hashlazy)
 import qualified Data.ByteString.Char8 as S
+import qualified Data.ByteString.Lazy.Char8  as L
 import qualified Data.CaseInsensitive  as CI (original)
 import qualified Data.HashSet as HashSet
 import qualified Network.HTTP.Client as HTTP
@@ -44,6 +44,17 @@
                Request -> IO Request
 signRequest AWSv4 = signRequestV4
 
+hexSha256Hash :: S.ByteString -> S.ByteString
+hexSha256Hash dta =
+  let digest = CT.hash dta :: CT.Digest CT.SHA256
+  in S.pack (show digest)
+
+hexSha256HashLazy :: L.ByteString -> S.ByteString
+hexSha256HashLazy dta =
+  let digest = CT.hashlazy dta :: CT.Digest CT.SHA256
+  in S.pack (show digest)
+
+
 signRequestV4 :: S.ByteString -> S.ByteString -> Request -> IO Request
 signRequestV4 key secret request = do
   !ts <- timestamp                         -- YYYYMMDDT242424Z, UTC based
@@ -55,7 +66,7 @@
       date = S.takeWhile (/= 'T') ts      -- YYYYMMDD
       hashedPayload
         | request ^. method `elem` ["POST", "PUT"] = payloadHash req
-        | otherwise = HEX.encode $ SHA256.hash ""
+        | otherwise = hexSha256Hash ""
       -- add common v4 signing headers, service specific headers, and
       -- drop tmp header and Runscope-Bucket-Auth header (if present).
       req = request & requestHeaders %~
@@ -87,7 +98,7 @@
           "AWS4-HMAC-SHA256"
         , ts
         , dateScope
-        , HEX.encode $ SHA256.hash canonicalReq
+        , hexSha256Hash canonicalReq
         ]
   -- task 3, steps 1 and 2
   let signature = ("AWS4" <> secret) &
@@ -113,16 +124,15 @@
     timestamp = render <$> getCurrentTime
       where render = S.pack . formatTime defaultTimeLocale "%Y%m%dT%H%M%SZ" .
                      utcToLocalTime utc -- UTC printable: YYYYMMDDTHHMMSSZ
-    hmac' s k = toBytes (hmacGetDigest h)
-      where h = hmac k s :: (CT.HMAC CT.SHA256)
+    hmac' :: S.ByteString -> S.ByteString -> S.ByteString
+    hmac' s k = convert (hmacGetDigest h)
+      where h = hmac k s :: (HMAC CT.SHA256)
 
 payloadHash :: Request -> S.ByteString
 payloadHash req =
   case HTTP.requestBody req of
-    HTTP.RequestBodyBS bs ->
-      HEX.encode $ SHA256.hash bs
-    HTTP.RequestBodyLBS lbs ->
-      HEX.encode $ SHA256.hashlazy lbs
+    HTTP.RequestBodyBS bs ->   hexSha256Hash bs
+    HTTP.RequestBodyLBS lbs -> hexSha256HashLazy lbs
     _ -> error "addTmpPayloadHashHeader: unexpected request body type"
 
 -- Per AWS documentation at:
@@ -179,5 +189,5 @@
   | otherwise = hostname
     where p1 "-"   = "."
           p1 other = other
-          p2 "--"   = "-"
-          p2 other  = other
+          p2 "--"  = "-"
+          p2 other = other
diff --git a/Network/Wreq/Session.hs b/Network/Wreq/Session.hs
--- a/Network/Wreq/Session.hs
+++ b/Network/Wreq/Session.hs
@@ -18,7 +18,7 @@
 --
 -- * Transparent cookie management.  Any cookies set by the server
 --   persist from one request to the next.  (Bypass this overhead
---   using 'withAPISession'.)
+--   using 'newAPISession'.)
 --
 --
 -- This module is designed to be used alongside the "Network.Wreq"
@@ -28,19 +28,20 @@
 -- import "Network.Wreq"
 -- import qualified "Network.Wreq.Session" as Sess
 --
--- main = Sess.'withSession' $ \\sess ->
+-- main = do
+--   sess <- Sess.'newSession'
 --   Sess.'get' sess \"http:\/\/httpbin.org\/get\"
 -- @
 --
--- We create a 'Session' using 'withSession', then pass the session to
+-- We create a 'Session' using 'newSession', then pass the session to
 -- subsequent functions.  When talking to a REST-like service that does
--- not use cookies, it is more efficient to use 'withAPISession'.
+-- not use cookies, it is more efficient to use 'newAPISession'.
 --
 -- Note the use of qualified import statements in the examples above,
 -- so that we can refer unambiguously to the 'Session'-specific
 -- implementation of HTTP GET.
 --
--- One 'Network.HTTP.Client.Manager' (possibly set with 'withSessionControl') is used for all
+-- One 'Network.HTTP.Client.Manager' (possibly set with 'newSessionControl') is used for all
 -- session requests. The manager settings in the 'Options' parameter
 -- for the 'getWith', 'postWith' and similar functions is ignored.
 
@@ -94,6 +95,7 @@
 import qualified Network.HTTP.Client as HTTP
 import qualified Network.Wreq.Internal.Lens as Lens
 import qualified Network.Wreq.Lens as Lens
+import Data.Traversable as T
 
 -- | Create a 'Session', passing it to the given function.  The
 -- 'Session' will no longer be valid after that function returns.
@@ -170,7 +172,7 @@
 --
 -- @since 0.5.2.0
 getSessionCookieJar :: Session -> IO (Maybe HTTP.CookieJar)
-getSessionCookieJar = traverse readIORef . seshCookies
+getSessionCookieJar = T.traverse readIORef . seshCookies
 
 -- | 'Session'-specific version of 'Network.Wreq.get'.
 get :: Session -> String -> IO (Response L.ByteString)
@@ -263,7 +265,7 @@
 
 runWithGeneric :: (resp -> Response b) -> Session -> (Req -> IO resp) -> Req -> IO resp
 runWithGeneric extract Session{..} act (Req _ req) = do
-  req' <- (\c -> req & Lens.cookieJar .~ c) <$> traverse readIORef seshCookies
+  req' <- (\c -> req & Lens.cookieJar .~ c) `fmap` T.traverse readIORef seshCookies
   resp <- act (Req (Right seshManager) req')
   forM_ seshCookies $ \ref ->
     writeIORef ref (HTTP.responseCookieJar (extract resp))
diff --git a/Network/Wreq/Types.hs b/Network/Wreq/Types.hs
--- a/Network/Wreq/Types.hs
+++ b/Network/Wreq/Types.hs
@@ -71,7 +71,7 @@
 instance Putable [Part] where
     putPayload p req =
         -- According to doc, formDataBody changes the request type to POST which is wrong; change it back
-        (\r -> r{method=method req}) <$> formDataBody p req
+        (\r -> r{method=method req}) `fmap` formDataBody p req
 
 instance Putable [(S.ByteString, S.ByteString)] where
     putPayload ps req =
diff --git a/changelog.md b/changelog.md
--- a/changelog.md
+++ b/changelog.md
@@ -1,5 +1,11 @@
 -*- markdown -*-
 
+2018-03-01 0.5.2.1
+
+* Fixed some building issues with older versions
+
+* Removed dependency on cryptohash, using cryptonite instead
+
 2018-01-01 0.5.2.0
 
 * Added some HistoriedResponse support
diff --git a/wreq.cabal b/wreq.cabal
--- a/wreq.cabal
+++ b/wreq.cabal
@@ -1,5 +1,5 @@
 name:                wreq
-version:             0.5.2.0
+version:             0.5.2.1
 synopsis:            An easy-to-use HTTP client library.
 description:
   .
@@ -36,7 +36,7 @@
 copyright:           2014 Bryan O'Sullivan
 category:            Web
 build-type:          Custom
-cabal-version:       >=1.24
+cabal-version:       >=1.10
 tested-with:         GHC==8.2.1, GHC==8.0.2, GHC==7.10.3, GHC==7.8.4, GHC==7.6.3, GHC==7.4.2
 extra-source-files:
   README.md
@@ -105,11 +105,10 @@
     authenticate-oauth >= 1.5,
     base >= 4.5 && < 5,
     base16-bytestring,
-    byteable,
     bytestring >= 0.9,
     case-insensitive,
     containers,
-    cryptohash,
+    cryptonite,
     exceptions >= 0.5,
     ghc-prim,
     hashable,
@@ -118,6 +117,7 @@
     http-types >= 0.8,
     lens >= 4.5,
     lens-aeson,
+    memory,
     mime-types,
     time-locale-compat,
     template-haskell,
diff --git a/www/tutorial.md b/www/tutorial.md
--- a/www/tutorial.md
+++ b/www/tutorial.md
@@ -435,7 +435,11 @@
 
 ~~~~ {.haskell}
 ghci> r <- get "http://httpbin.org/basic-auth/user/pass"
-*** Exception: StatusCodeException (Status {statusCode = 401, {-...-}
+*** Exception: HttpExceptionRequest Request { ... }
+ (StatusCodeException (Response {
+    responseStatus = Status {statusCode = 401, {-...-} }
+    , {- ... -}
+ }), "..." )
 ~~~~
 
 If we then supply a username and password, our request will succeed.
@@ -516,7 +520,11 @@
 
 ~~~~ {.haskell}
 h> r <- get "http://httpbin.org/wibblesticks"
-*** Exception: StatusCodeException (Status {statusCode = 404, {-...-}
+*** Exception: HttpExceptionRequest Request { ... }
+ (StatusCodeException (Response {
+    responseStatus = Status {statusCode = 404, {-...-} }
+    , {- ... -}
+ }), "..." )
 ~~~~
 
 Here's a simple example of how we can respond to one kind of error: a
@@ -526,17 +534,19 @@
 ~~~~ {.haskell}
 import Control.Exception as E
 import Control.Lens
-import Network.HTTP.Client
+import Network.HTTP.Client (HttpException (HttpExceptionRequest),
+                            HttpExceptionContent (StatusCodeException))
 import Network.Wreq
 
 getAuth url myauth = get url `E.catch` handler
   where
-    handler e@(StatusCodeException s _ _)
-      | s ^. statusCode == 401 = getWith authopts authurl
-      | otherwise              = throwIO e
-      where authopts = defaults & auth .~ myauth
-            -- switch to TLS when we use auth
-            authurl = "https" ++ dropWhile (/=':') url
+    handler e@(HttpExceptionRequest _ (StatusCodeException r _))
+      | r ^. responseStatus . statusCode == 401 = getWith authopts authurl
+      | otherwise                               = throwIO e
+    handler e = throwIO e
+    authopts = defaults & auth ?~ myauth
+    -- switch to TLS when we use auth
+    authurl = "https" ++ dropWhile (/=':') url
 ~~~~
 
 (A "real world" version would remember which URLs required
@@ -573,7 +583,8 @@
 import qualified Network.Wreq.Session as S
 
 main :: IO ()
-main = S.withSession $ \sess -> do
+main = do
+  sess <- S.newSession
   -- First request: tell the server to set a cookie
   S.get sess "http://httpbin.org/cookies/set?name=hi"
 
@@ -589,8 +600,7 @@
   module qualified, and we'll identify its functions by prefixing them
   with "`S.`".
 
-* To create a `Session`, we use `S.withSession`. It calls our code
-  with `sess`, the `Session` value we'll use.
+* To create a `Session`, we use `S.newSession`.
 
 * Instead of `get` and `post`, we call the `Session`-specific
   versions, [`S.get`](http://hackage.haskell.org/package/wreq/docs/Network-Wreq-Session.html#v:get) and [`S.post`](http://hackage.haskell.org/package/wreq/docs/Network-Wreq-Session.html#v:post), and pass `sess` to each of them.
