diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,20 @@
+Copyright (c) 2015 aaron levin
+
+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/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,72 @@
+Free Your Client... and Your Requests Will Follow
+=================================================
+
+`free-http` is an http-client based on Free Monads. `free-http` exposes a Free Monad to express standard http verbs as well as several backends to interpet programs written in the free monad using various http clients (currently: a pure client, an `http-client`-backed client, and a random client).
+
+See [here](https://github.com/aaronlevin/free-http/blob/master/src/Network/HTTP/Client/Free/Examples.hs#L152) for an example.
+
+To use free-http, simply:
+
+1. Import Network.HTTP.Client.Free to use the library.
+2. Choose your base request type by defining your own instance of the `RequestType` type family or importing one from an interpreter. E.g.
+
+  ```
+  data MyClient
+  type instance RequestType MyClient = Request
+  ```
+
+  or
+
+  ```
+  import Network.HTTP.Free.Client.HttpClient (HttpClient)
+  ```
+
+3. Choose your base response type by defining your own instance of the `ResponseTYpe` type family or importing one from an interpreter. E.g.  
+
+  ```
+  type instance ResponseType MyClient = Response ByteString
+  ```
+
+  or
+
+  ```
+  import Network.HTTP.Free.Client.HttpClient (HttpClient)
+  ```
+
+4. Write a program in the 'FreeHttp MyClient m a' free monad.
+5. Import an interpreter, such as 'HttpClient'
+
+  ```
+  import Network.HTTP.Free.Client.HttpClient
+  ```
+
+6. Run your program against the interpreter:
+
+  ```
+  runHttp (myProgram :: FreeHttp MyClient IO String)
+  ```
+
+## Design Choices
+
+### `RequestType` and `ResponseType`
+
+Haskell is fortunate to have several very well-designed http clients: [http-client](https://hackage.haskell.org/package/http-client-0.4.16/docs/Network-HTTP-Client.html), [wreq](http://www.serpentine.com/wreq/), [http-conduit](https://hackage.haskell.org/package/http-conduit), [pipes-http](https://hackage.haskell.org/package/pipes-http), etc. Unfortunately, a few of those clients support several different *Request* and *Response* types. To keep `free-http` flexible, we use two type families defined as:
+
+```
+type family RequestType client  :: *
+type family ResponseType client :: *
+```
+
+Our `HttpF` functor is thus defined as:
+
+```
+data HttpF client a = HttpF StdMethod (RequestType client) (ResponseType client -> a)
+                    deriving Functor
+```
+
+This allows our `HttpF` functor to be agnostic of the foundational request and response type, while allowing interpreter authors to specify the concrete types they need for their http client libraries (e.g. `Request` in the case of `http-client`). A consequence of this is that `free-http` clients (you) need to specify, at some point, the foundation you're using. This can be done in two ways:
+
+1. You can define your own foundation (see above).
+2. You can import one from an interpreter.
+
+To specify your request and response foundation, use replace the `client` type in `HttpF client a` or `FreeHttp client m a` to the type signalling your foundation. For example, the http-client, pure, and arbitrary interpreters use `HttpClient`, `PureClient`, and `ArbitraryClient` respectively.
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/free-http.cabal b/free-http.cabal
new file mode 100644
--- /dev/null
+++ b/free-http.cabal
@@ -0,0 +1,94 @@
+name:                free-http
+
+version:             0.1.0.1
+
+synopsis:            An HTTP Client based on Free Monads.
+
+description:         `free-http` is an http-client based on Free Monads.
+                     `free-http` exposes a Free Monad to express standard http
+                     verbs as well as several backends to interpet programs
+                     written in the free monad using various http clients
+                     (currently: a pure client, an `http-client`-backed client,
+                     and a random client).
+
+                     To use free-http, simply:
+
+                     1. Import Network.HTTP.Client.Free to use the library.
+                     2. Choose your base request type by defining your own
+                        instance of the `RequestType` type family or importing
+                        one from an interpreter. E.g.
+
+                        data MyClient
+                        type instance RequestType MyClient = Request
+
+                        (or)
+
+                        import Network.HTTP.Free.Client.HttpClient (HttpClient)
+
+                     3. Choose your base response type by defining your own
+                        instance of the `ResponseTYpe` type family or importing
+                        one from an interpreter. E.g. 
+
+                        type instance ResponseType MyClient = Response ByteString
+
+                        (or)
+
+                        import Network.HTTP.Free.Client.HttpClient (HttpClient)
+
+                     4. Write a program in the 'FreeHttp MyClient m a' free monad.
+                     5. Import an interpreter, such as 'HttpClient'
+
+                        import Network.HTTP.Free.Client.HttpClient
+
+                     6. Run your program against the interpreter:
+
+                        runHttp (myProgram :: FreeHttp MyClient IO String)
+
+homepage:            https://github.com/aaronlevin/free-http
+
+license:             MIT
+
+license-file:        LICENSE
+
+author:              Aaron Levin
+
+maintainer:          vilevin@gmail.com
+
+category:            Network
+
+build-type:          Simple
+
+extra-source-files:  README.md
+                   , LICENSE
+
+cabal-version:       >=1.10
+
+source-repository head
+  type: git
+  location: git://github.com/aaronlevin/free-http.git
+
+library
+  exposed-modules:     Network.HTTP.Client.Free.ArbitraryClient
+                       Network.HTTP.Client.Free.HttpClient
+                       Network.HTTP.Client.Free.PureClient
+                       Network.HTTP.Client.Free.Types
+                       Network.HTTP.Client.Free.Util
+
+  other-modules:       Network.HTTP.Client.Free.Examples
+
+  -- other-extensions:    
+
+  build-depends:       base         > 4.6 && < 4.9
+                     , bytestring   >= 0.10.0.0
+                     , free         >= 4.0
+                     , http-client  >= 0.4.0
+                     , http-types   >= 0.8.0
+                     , mtl          >= 2.0.0.0
+                     , QuickCheck   >= 2.7
+                     , text         >= 1.0.0.0
+                     , time         >= 1.4.0.1
+                     , transformers >= 0.4.0.0
+
+  hs-source-dirs:      src
+
+  default-language:    Haskell2010
diff --git a/src/Network/HTTP/Client/Free/ArbitraryClient.hs b/src/Network/HTTP/Client/Free/ArbitraryClient.hs
new file mode 100644
--- /dev/null
+++ b/src/Network/HTTP/Client/Free/ArbitraryClient.hs
@@ -0,0 +1,71 @@
+{-| An interpreter that fails randomly
+-}
+
+{-# LANGUAGE TypeFamilies #-}
+
+module Network.HTTP.Client.Free.ArbitraryClient where
+
+import Control.Monad.IO.Class (MonadIO, liftIO)
+import           Control.Monad.Trans             (MonadTrans, lift)
+import           Control.Monad.Trans.Free.Church (FT, iterT, iterTM, liftF)
+import Control.Applicative ((<$>))
+import Network.HTTP.Client.Free.Types (HttpF(HttpF), ResponseType)
+import           Test.QuickCheck           (Arbitrary, arbitrary, sample')
+
+-------------------------------------------------------------------------------
+-- | Peel a layer of the 'HttpF' functor and generate a random Response.
+iterTHttp :: ( r ~ ResponseType client
+             , Arbitrary r
+             , Monad m
+             , MonadIO m
+             )
+          => HttpF client (m a)
+          -> m a
+iterTHttp (HttpF _ _ next) = head <$> liftIO (sample' arbitrary) >>= next
+
+-------------------------------------------------------------------------------
+-- | Peel a layer of the 'HttpF' functor and generate a random Response. This 
+-- time the base monad is 't m'.
+iterTMHttp :: ( r ~ ResponseType client
+              , Arbitrary r
+              , Monad m
+              , MonadIO m
+              , MonadTrans t
+              , Monad (t m)
+              )
+           => HttpF client (t m a)
+           -> t m a
+iterTMHttp (HttpF _ _ next) = head <$> (lift . liftIO) (sample' arbitrary) >>= next
+
+-------------------------------------------------------------------------------
+-- | The main http-client interpreter. The client is free to specify the base
+-- effect monad so long as there is an instance of 'MonadIO' for it in scope.
+runHttp :: ( r ~ ResponseType client
+           , Arbitrary r
+           , Monad m
+           , MonadIO m
+           )
+        => ignore
+        -- ^ a paramter that will be ignored. It is included so client's can
+        -- hot-swap interpreters.
+        -> FT (HttpF client) m a
+        -> m a
+runHttp = const (iterT iterTHttp)
+
+-------------------------------------------------------------------------------
+-- | The main http-client interpreter. The client is free to specify the base
+-- effect monad ('m'), and in thise case this the result can be lifted into a
+-- higher monad transformer stack ('t')
+runTHttp :: ( r ~ ResponseType client
+            , Arbitrary r
+            , Monad m
+            , MonadIO m
+            , MonadTrans t
+            , Monad (t m)
+            )
+         => ignore
+         -- ^ a paramter that will be ignored. It is included so client's can
+         -- hot-swap interpreters.
+         -> FT (HttpF client) m a
+         -> t m a
+runTHttp = const (iterTM iterTMHttp)
diff --git a/src/Network/HTTP/Client/Free/Examples.hs b/src/Network/HTTP/Client/Free/Examples.hs
new file mode 100644
--- /dev/null
+++ b/src/Network/HTTP/Client/Free/Examples.hs
@@ -0,0 +1,183 @@
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE TypeFamilies #-}
+
+module Network.HTTP.Client.Free.Examples (
+) where
+
+import Control.Applicative ((<$>), (<*>))
+import Data.ByteString (ByteString)
+import Data.ByteString.Char8 (pack)
+import Data.Maybe (fromJust)
+import Data.Time (UTCTime(UTCTime), fromGregorian)
+import Network.HTTP.Types.Header
+import Network.HTTP.Types.Status
+import           Network.HTTP.Types.Method (StdMethod (..))
+import Network.HTTP.Types.Version (http09, http10, http11, HttpVersion)
+import Network.HTTP.Client (defaultManagerSettings, newManager, parseUrl, responseStatus, Request)
+import Network.HTTP.Client.Free (get)
+import qualified Network.HTTP.Client.Free.ArbitraryClient as ArbitraryClient
+import Network.HTTP.Client.Free.HttpClient (HttpClient)
+import qualified Network.HTTP.Client.Free.HttpClient as HttpClient
+import Network.HTTP.Client.Free.Types (FreeHttp, RequestType, ResponseType)
+import Network.HTTP.Client.Internal (Cookie(Cookie), CookieJar, createCookieJar, Response(Response), ResponseClose(ResponseClose))
+import           Test.QuickCheck           (choose, Gen, Arbitrary(arbitrary), elements, listOf, sample', suchThat)
+
+-- | an arbitrary 'Status'
+arbStatus :: Gen Status
+arbStatus = elements [ status100
+                     , status101
+                     , status200
+                     , status201
+                     , status203
+                     , status204
+                     , status205
+                     , status206
+                     , status300
+                     , status301
+                     , status302
+                     , status303
+                     , status304
+                     , status305
+                     , status307
+                     , status400
+                     , status401
+                     , status402
+                     , status403
+                     , status404
+                     , status405
+                     , status406
+                     , status407
+                     , status408
+                     , status409
+                     , status410
+                     , status411
+                     , status412
+                     , status413
+                     , status414
+                     , status415
+                     , status416
+                     , status417
+                     , status418
+                     , status428
+                     , status429
+                     , status431
+                     , status500
+                     , status501
+                     , status502
+                     , status503
+                     , status504
+                     , status505
+                     , status511
+                     ]
+
+-- | an arbitrary 'HttpVersion'
+arbHttpVersion :: Gen HttpVersion
+arbHttpVersion = elements [ http09
+                          , http10
+                          , http11
+                          ]
+
+-- | an arbitrary 'HeaderName'
+arbHeaderName :: Gen HeaderName
+arbHeaderName = elements [ hAccept
+                         , hAcceptLanguage
+                         , hAuthorization
+                         , hCacheControl
+                         , hConnection
+                         , hContentEncoding
+                         , hContentLength
+                         , hContentMD5
+                         , hContentType
+                         , hCookie
+                         , hDate
+                         , hIfModifiedSince
+                         , hIfRange
+                         , hLastModified
+                         , hLocation
+                         , hRange
+                         , hReferer
+                         , hServer
+                         , hUserAgent
+                         ]
+
+-- | an arbitrary Header. This is not performant, but you shouldn't
+-- be using this client in production anyway.
+arbHeader :: Gen Header
+arbHeader = (,) <$> arbHeaderName <*> fmap pack arbitrary
+
+-- | an arbitrary UTCTime
+arbUtcTime :: Gen UTCTime
+arbUtcTime = do
+    rDay <- choose (1,29) :: Gen Int
+    rMonth <- choose (1,12) :: Gen Int
+    rYear <- choose (1970, 2015) :: Gen Integer
+    rTime <- choose (0,86401) :: Gen Int
+    return $ UTCTime (fromGregorian rYear rMonth rDay) (fromIntegral rTime)
+
+-- | an arbtirary Cookie
+arbCookie :: Gen Cookie
+arbCookie = do
+    cCreationTime    <- arbUtcTime
+    cLastAccessTime  <- suchThat arbUtcTime (cCreationTime >=)
+    cExpiryTime      <- suchThat arbUtcTime (cLastAccessTime >=)
+    cName           <- fmap pack arbitrary
+    cValue          <- fmap pack arbitrary
+    cDomain         <- fmap pack arbitrary
+    cPath           <- fmap pack arbitrary
+    cPersistent     <- arbitrary
+    cHostOnly       <- arbitrary
+    cSecureOnly     <- arbitrary
+    cHttpOnly       <- arbitrary
+    return $ Cookie cName
+                    cValue
+                    cExpiryTime
+                    cDomain
+                    cPath
+                    cCreationTime
+                    cLastAccessTime
+                    cPersistent
+                    cHostOnly
+                    cSecureOnly
+                    cHttpOnly
+
+-- | unexported instance for arbitrary responses
+instance Arbitrary (Response ByteString) where
+    arbitrary = Response <$> arbStatus
+                         <*> arbHttpVersion
+                         <*> listOf arbHeader
+                         <*> (pack <$> arbitrary)
+                         <*> (createCookieJar <$> listOf arbCookie)
+                         <*> return (ResponseClose (return ()))
+
+-- | A sample request
+weirdReq :: Request
+weirdReq = fromJust (parseUrl "http://weirdcanada.com/api")
+
+-- | A program that checks to see if the weird canada api is up.
+checkWeird :: ( Request ~ RequestType client
+              , Response b ~ ResponseType client
+              , Monad m
+              )
+           => FreeHttp client m Bool
+checkWeird = do
+    resp <- get weirdReq
+    (return . (== status200) . responseStatus) resp
+
+data ExampleClient
+type instance RequestType ExampleClient = Request
+type instance ResponseType ExampleClient = Response ByteString
+
+main :: IO ()
+main = do
+    -- a result using the arbitrary interpreter
+    arbResult <- ArbitraryClient.runHttp () (checkWeird :: FreeHttp ExampleClient IO Bool)
+    putStrLn ("Arbitrary client returned: " ++ show arbResult)
+
+    -- a result using the actual http client
+    mgr <- newManager defaultManagerSettings
+    realResult <- HttpClient.runHttp mgr (checkWeird :: FreeHttp HttpClient IO Bool)
+
+    putStrLn ("http-client returned: " ++ show realResult)
+
+
+
diff --git a/src/Network/HTTP/Client/Free/HttpClient.hs b/src/Network/HTTP/Client/Free/HttpClient.hs
new file mode 100644
--- /dev/null
+++ b/src/Network/HTTP/Client/Free/HttpClient.hs
@@ -0,0 +1,71 @@
+{-| An Interpreter with http-client as the foundation
+-}
+{-# LANGUAGE BangPatterns   #-}
+{-# LANGUAGE EmptyDataDecls #-}
+{-# LANGUAGE TypeFamilies   #-}
+
+module Network.HTTP.Client.Free.HttpClient (
+    HttpClient
+    , runHttp
+    , runTHttp
+) where
+
+import           Control.Monad.IO.Class          (MonadIO, liftIO)
+import           Control.Monad.Trans             (MonadTrans, lift)
+import           Control.Monad.Trans.Free.Church (FT, iterT, iterTM, liftF)
+import           Data.ByteString.Lazy            (ByteString)
+import           Network.HTTP.Client             (Manager, Request, Response,
+                                                  httpLbs)
+import           Network.HTTP.Client.Free.Types  (HttpF (HttpF), RequestType,
+                                                  ResponseType)
+import           Network.HTTP.Client.Free.Util   (setMethod)
+import           Network.HTTP.Types.Method       (renderStdMethod)
+
+-------------------------------------------------------------------------------
+-- | 'HttpClient' is an uninhabited type used to identify the http-client
+-- based interpreter
+data HttpClient
+
+-------------------------------------------------------------------------------
+-- | HttpClient expects 'Request's and returns 'Response ByteString's
+type instance RequestType  HttpClient = Request
+type instance ResponseType HttpClient = Response ByteString
+
+-------------------------------------------------------------------------------
+-- | Peel a layer of the 'HttpF' functor and run an http request with the data
+-- provided.
+iterTHttp :: (Monad m, MonadIO m)
+          => Manager
+          -> HttpF HttpClient (m a)
+          -> m a
+iterTHttp manager (HttpF m r next) =
+    let !req = setMethod m r in liftIO (httpLbs req manager) >>= next
+
+-------------------------------------------------------------------------------
+-- | Peel a layer of the 'HttpF' functor and run an http request with the data.
+-- the base monad for this action is 't m'.
+iterTMHttp :: (Monad m, MonadTrans t, Monad (t m), MonadIO m)
+    => Manager
+    -> HttpF HttpClient (t m a)
+    -> t m a
+iterTMHttp manager (HttpF m r next) =
+    let !req = setMethod m r in (lift . liftIO $ httpLbs req manager) >>= next
+
+-------------------------------------------------------------------------------
+-- | The main http-client interpreter. The client is free to specify the base
+-- effect monad so long as there is an instance of 'MonadIO' for it in scope.
+runHttp :: (Monad m, MonadIO m)
+         => Manager
+         -> FT (HttpF HttpClient) m a
+         -> m a
+runHttp manager = iterT (iterTHttp manager)
+
+-------------------------------------------------------------------------------
+-- | The main http-client interpreter. The client is free to specify the base
+-- effect monad ('m'), and in thise case this the result can be lifted into a
+-- higher monad transformer stack ('t')
+runTHttp :: (Monad m, MonadIO m, MonadTrans t, Monad (t m))
+        => Manager
+        -> FT (HttpF HttpClient) m a
+        -> t m a
+runTHttp manager = iterTM (iterTMHttp manager)
diff --git a/src/Network/HTTP/Client/Free/PureClient.hs b/src/Network/HTTP/Client/Free/PureClient.hs
new file mode 100644
--- /dev/null
+++ b/src/Network/HTTP/Client/Free/PureClient.hs
@@ -0,0 +1,61 @@
+{-| A pure interepreter
+-}
+
+{-# LANGUAGE RankNTypes   #-}
+{-# LANGUAGE TypeFamilies #-}
+
+module Network.HTTP.Client.Free.PureClient (
+      runHttp
+    , runTHttp
+) where
+
+import           Control.Monad.Trans             (MonadTrans)
+import           Control.Monad.Trans.Free.Church (FT, iterT, iterTM, liftF)
+import           Network.HTTP.Client             (Manager, Request, Response,
+                                                  httpLbs)
+import           Network.HTTP.Client.Free.Types  (HttpF (HttpF), RequestType,
+                                                  ResponseType)
+
+-------------------------------------------------------------------------------
+-- | Peel a layer of the 'HttpF' functor and, given the pure, mock function
+-- that maps requests to responses, run the next method against the returned
+-- request.
+iterTHttp :: (Monad m)
+          => (RequestType client -> ResponseType client)
+          -- ^ a function to mock requests
+          -> HttpF client (m a)
+          -> m a
+iterTHttp mock (HttpF _ req next) = next (mock req)
+
+-------------------------------------------------------------------------------
+-- | Peel a layer of the 'HttpF' functor and, given the pure, mock function
+-- that maps requests to responses, run the next method against the returned
+-- request. the base monad for this action is `t m a`
+iterTMHttp :: (Monad m, MonadTrans t, Monad (t m))
+           => (RequestType client -> ResponseType client)
+           -> HttpF client (t m a)
+           -> t m a
+iterTMHttp mock (HttpF _ req next) = next (mock req)
+
+-------------------------------------------------------------------------------
+-- | A pure interpreter based on a client-supplied mocking function
+runHttp :: Monad m
+        => ignore
+        -- ^ a parameter that will be ignored. It is included so client's can
+        -- hot-swap interpreters (many will require a `Manager` type)
+        -> (RequestType client -> ResponseType client)
+        -> FT (HttpF client) m a
+        -> m a
+runHttp _ mock = iterT (iterTHttp mock)
+
+-------------------------------------------------------------------------------
+-- | A pure interpreter based on a client-supplied mocking function. The under-
+-- lying monad is `t m`, so computations will be lifted into `t m`.
+runTHttp :: (Monad m, MonadTrans t, Monad (t m))
+         => ignore
+         -- ^ a paramter that will be ignored. It is included so client's can
+         -- host-swap interpreters (many will require a 'Manager' type)
+         -> (RequestType client -> ResponseType client)
+         -> FT (HttpF client) m a
+         -> t m a
+runTHttp _ mock = iterTM (iterTMHttp mock)
diff --git a/src/Network/HTTP/Client/Free/Types.hs b/src/Network/HTTP/Client/Free/Types.hs
new file mode 100644
--- /dev/null
+++ b/src/Network/HTTP/Client/Free/Types.hs
@@ -0,0 +1,33 @@
+{-| The primary Free Monad wrapping HTTP actions.
+-}
+
+{-# LANGUAGE DeriveFunctor #-}
+{-# LANGUAGE TypeFamilies #-}
+
+module Network.HTTP.Client.Free.Types (
+    -- * Type Familes
+      RequestType
+    , ResponseType
+
+    -- * The base functor of our library
+    , HttpF(HttpF)
+
+    -- * Type aliases
+    , FreeHttp
+) where
+
+import Control.Monad.Trans.Free.Church (FT)
+import Network.HTTP.Types.Method (StdMethod)
+
+-- | type family to represent the request type foundation
+type family RequestType  client :: *
+
+-- | type family to represent the response type foundation
+type family ResponseType client :: *
+
+-- | Our functor from which the free-http free monad is generated from.
+data HttpF client a = HttpF StdMethod (RequestType client) (ResponseType client -> a)
+                    deriving Functor
+
+-- | a type alias for the free monad generated by 'HttpF'
+type FreeHttp client m a = FT (HttpF client) m a
diff --git a/src/Network/HTTP/Client/Free/Util.hs b/src/Network/HTTP/Client/Free/Util.hs
new file mode 100644
--- /dev/null
+++ b/src/Network/HTTP/Client/Free/Util.hs
@@ -0,0 +1,15 @@
+{-| Utilities for working with networking types
+-}
+
+{-# LANGUAGE BangPatterns #-}
+
+module Network.HTTP.Client.Free.Util (
+    setMethod
+) where
+
+import           Network.HTTP.Client       (Request (method))
+import           Network.HTTP.Types.Method (StdMethod, renderStdMethod)
+
+-- | set the method of a request, overriding the previous method.
+setMethod :: StdMethod -> Request -> Request
+setMethod m req = let !nMethod = renderStdMethod m in req { method = nMethod }
