diff --git a/.github/workflows/code-style.yaml b/.github/workflows/code-style.yaml index c439be2ab..b6d456f05 100644 --- a/.github/workflows/code-style.yaml +++ b/.github/workflows/code-style.yaml @@ -1,4 +1,4 @@ -name: Code style check +name: Code style checks concurrency: group: formatting-${{ github.ref_name }} @@ -20,4 +20,17 @@ jobs: uses: cachix/install-nix-action@v31 - name: Check code formatting run: | - nix develop '#haskellFormatter' --command fourmolu --mode=check --check-idempotence servant servant-* \ No newline at end of file + nix develop '#haskellFormatter' --command fourmolu --mode=check --check-idempotence servant servant-* + + lint: + runs-on: ubuntu-latest + steps: + - name: Checkout Code + uses: actions/checkout@v4 + with: + fetch-depth: 1 + - name: Install Nix + uses: cachix/install-nix-action@v31 + - name: Run hlint check + run: | + nix develop '#haskellLinter' --command hlint servant servant-* \ No newline at end of file diff --git a/hlint.yaml b/.hlint.yaml similarity index 90% rename from hlint.yaml rename to .hlint.yaml index 5328fef48..015b942cc 100644 --- a/hlint.yaml +++ b/.hlint.yaml @@ -45,15 +45,12 @@ # # Generalise map to fmap, ++ to <> # - group: {name: generalise, enabled: true} +# +# Replace return with pure +- group: {name: future, enabled: true} # Ignore some builtin hints -- ignore: {name: Redundant do} -- ignore: {name: Parse error} -- ignore: {name: Use fmap} -- ignore: {name: Use list comprehension} -- ignore: {name: Use lambda-case} -- ignore: {name: Eta reduce} # - ignore: {name: Use const, within: SpecialModule} # Only within certain modules diff --git a/doc/cookbook/basic-auth/BasicAuth.lhs b/doc/cookbook/basic-auth/BasicAuth.lhs index 2b90df93d..aeeb3df87 100644 --- a/doc/cookbook/basic-auth/BasicAuth.lhs +++ b/doc/cookbook/basic-auth/BasicAuth.lhs @@ -71,7 +71,7 @@ api :: Proxy API api = Proxy server :: Server API -server usr = return (site usr) +server usr = pure (site usr) ``` In order to protect our endpoint (`"mysite" :> Get '[JSON] Website`), we simply @@ -105,10 +105,10 @@ checkBasicAuth db = BasicAuthCheck $ \basicAuthData -> password = decodeUtf8 (basicAuthPassword basicAuthData) in case Map.lookup username db of - Nothing -> return NoSuchUser + Nothing -> pure NoSuchUser Just u -> if pass u == password - then return (Authorized u) - else return BadPassword + then pure (Authorized u) + else pure BadPassword ``` This check simply looks up the user in the "database" and makes sure the diff --git a/doc/cookbook/basic-streaming/Streaming.lhs b/doc/cookbook/basic-streaming/Streaming.lhs index 7e4a4f90d..89dd63ef4 100644 --- a/doc/cookbook/basic-streaming/Streaming.lhs +++ b/doc/cookbook/basic-streaming/Streaming.lhs @@ -8,12 +8,12 @@ In other words, without streaming libraries. - Some basic usage doesn't require usage of streaming libraries, like `conduit`, `pipes`, `machines` or `streaming`. We have bindings for them though. -- Similar example is bundled with each of our streaming library interop packages (see +- Similar example is bundled with each of our streaming library interop packages (see [servant-pipes](https://github.com/haskell-servant/servant/blob/master/servant-pipes/example/Main.hs), [servant-conduit](https://github.com/haskell-servant/servant/blob/master/servant-conduit/example/Main.hs) and [servant-machines](https://github.com/haskell-servant/servant/blob/master/servant-machines/example/Main.hs)) - `SourceT` doesn't have *Prelude* with handy combinators, so we have to write - things ourselves. (Note to self: `mapM` and `foldM` would be handy to have). + things ourselves. (Note to self: `mapM` and `foldM` would be handy to have). ## Code @@ -64,19 +64,19 @@ server :: Server API server = fast :<|> slow :<|> readme :<|> proxy where fast n = liftIO $ do putStrLn $ "/get/" ++ show n - return $ fastSource n + pure $ fastSource n slow n = liftIO $ do putStrLn $ "/slow/" ++ show n - return $ slowSource n + pure $ slowSource n readme = liftIO $ do putStrLn "/proxy" - return (S.readFile "README.md") + pure (S.readFile "README.md") proxy c = liftIO $ do putStrLn "/proxy" - return c + pure c -- for some reason unfold leaks? fastSource = S.fromStepT . mk where @@ -116,8 +116,8 @@ main = do x <- S.unSourceT src (go (0 :: Int)) print x where - go !acc S.Stop = return acc - go !acc (S.Error err) = print err >> return acc + go !acc S.Stop = pure acc + go !acc (S.Error err) = print err >> pure acc go !acc (S.Skip s) = go acc s go !acc (S.Effect ms) = ms >>= go acc go !acc (S.Yield _ s) = go (acc + 1) s diff --git a/doc/cookbook/curl-mock/CurlMock.lhs b/doc/cookbook/curl-mock/CurlMock.lhs index 5ed3b1a2f..4e45b9823 100644 --- a/doc/cookbook/curl-mock/CurlMock.lhs +++ b/doc/cookbook/curl-mock/CurlMock.lhs @@ -141,10 +141,10 @@ generateEndpoint :: Text -> Req Mocked -> IO Text generateEndpoint host req = case maybeBody of Just body -> - body >>= \b -> return $ T.intercalate " " [ "curl", "-X", method, "-d", "'" <> b <> "'" + body >>= \b -> pure $ T.intercalate " " [ "curl", "-X", method, "-d", "'" <> b <> "'" , "-H 'Content-Type: application/json'", host <> "/" <> url ] Nothing -> - return $ T.intercalate " " [ "curl", "-X", method, host <> "/" <> url ] + pure $ T.intercalate " " [ "curl", "-X", method, host <> "/" <> url ] where method = decodeUtf8 $ req ^. reqMethod diff --git a/doc/cookbook/custom-errors/CustomErrors.lhs b/doc/cookbook/custom-errors/CustomErrors.lhs index 49d721a98..2dee12b67 100644 --- a/doc/cookbook/custom-errors/CustomErrors.lhs +++ b/doc/cookbook/custom-errors/CustomErrors.lhs @@ -67,12 +67,12 @@ server :: Server TestApi server = helloH :<|> postGreetH :<|> deleteGreetH where helloH name Nothing = helloH name (Just False) - helloH name (Just False) = return . Greet $ "Hello, " <> name - helloH name (Just True) = return . Greet . Text.toUpper $ "Hello, " <> name + helloH name (Just False) = pure . Greet $ "Hello, " <> name + helloH name (Just True) = pure . Greet . Text.toUpper $ "Hello, " <> name - postGreetH greet = return greet + postGreetH greet = pure greet - deleteGreetH _ = return NoContent + deleteGreetH _ = pure NoContent ``` ## Error formatters diff --git a/doc/cookbook/db-mysql-basics/MysqlBasics.lhs b/doc/cookbook/db-mysql-basics/MysqlBasics.lhs index 1040ea8c2..911d4570d 100644 --- a/doc/cookbook/db-mysql-basics/MysqlBasics.lhs +++ b/doc/cookbook/db-mysql-basics/MysqlBasics.lhs @@ -141,9 +141,9 @@ doMigration :: IO () doMigration = runNoLoggingT $ runResourceT $ withMySQLConn connInfo $ runReaderT $ runMigration migrateAll server :: Server Api -server = - personGET :<|> - personGETById :<|> +server = + personGET :<|> + personGETById :<|> personDELETE :<|> personPOST where @@ -155,20 +155,20 @@ server = selectPersons :: Handler [Person] selectPersons = do personList <- runDB $ selectList [] [] - return $ map (\(Entity _ u) -> u) personList + pure $ map (\(Entity _ u) -> u) personList selectPersonById :: Int -> Handler Person selectPersonById id = do sqlResult <- runDB $ get $ PersonKey id case sqlResult of - Just person -> return person + Just person -> pure person Nothing -> throwError err404 { errBody = JSON.encode "Person with ID not found." } createPerson :: Person -> Handler Person createPerson person = do attemptCreate <- runDB $ insert person case attemptCreate of - PersonKey k -> return person + PersonKey k -> pure person _ -> throwError err503 { errBody = JSON.encode "Could not create Person." } deletePerson :: Int -> Handler () diff --git a/doc/cookbook/db-postgres-pool/PostgresPool.lhs b/doc/cookbook/db-postgres-pool/PostgresPool.lhs index 8cda452aa..9c383f7b1 100644 --- a/doc/cookbook/db-postgres-pool/PostgresPool.lhs +++ b/doc/cookbook/db-postgres-pool/PostgresPool.lhs @@ -51,7 +51,7 @@ initDB :: DBConnectionString -> IO () initDB connstr = bracket (connectPostgreSQL connstr) close $ \conn -> do execute_ conn "CREATE TABLE IF NOT EXISTS messages (msg text not null)" - return () + pure () ``` Next, our server implementation. It will be parametrised (take as @@ -76,7 +76,7 @@ server conns = postMessage :<|> getMessages execute conn "INSERT INTO messages VALUES (?)" (Only msg) - return NoContent + pure NoContent getMessages :: Handler [Message] getMessages = fmap (map fromOnly) . liftIO $ diff --git a/doc/cookbook/db-sqlite-simple/DBConnection.lhs b/doc/cookbook/db-sqlite-simple/DBConnection.lhs index 514e70a74..925e4d3c9 100644 --- a/doc/cookbook/db-sqlite-simple/DBConnection.lhs +++ b/doc/cookbook/db-sqlite-simple/DBConnection.lhs @@ -59,7 +59,7 @@ server dbfile = postMessage :<|> getMessages execute conn "INSERT INTO messages VALUES (?)" (Only msg) - return NoContent + pure NoContent getMessages :: Handler [Message] getMessages = fmap (map fromOnly) . liftIO $ diff --git a/doc/cookbook/file-upload/FileUpload.lhs b/doc/cookbook/file-upload/FileUpload.lhs index 74d06d3f1..a79849c53 100644 --- a/doc/cookbook/file-upload/FileUpload.lhs +++ b/doc/cookbook/file-upload/FileUpload.lhs @@ -82,7 +82,7 @@ upload multipartData = do let content = fdPayload file putStrLn $ "Content of " ++ show (fdFileName file) LBS.putStr content - return 0 + pure 0 startServer :: IO () startServer = run 8080 (serve api upload) diff --git a/doc/cookbook/https/Https.lhs b/doc/cookbook/https/Https.lhs index 6a95824d1..6105c31b9 100644 --- a/doc/cookbook/https/Https.lhs +++ b/doc/cookbook/https/Https.lhs @@ -27,7 +27,7 @@ api :: Proxy API api = Proxy server :: Server API -server = return 10 +server = pure 10 app :: Application app = serve api server diff --git a/doc/cookbook/managed-resource/ManagedResource.lhs b/doc/cookbook/managed-resource/ManagedResource.lhs index b3d10601d..e09e00462 100644 --- a/doc/cookbook/managed-resource/ManagedResource.lhs +++ b/doc/cookbook/managed-resource/ManagedResource.lhs @@ -43,7 +43,7 @@ newHandle = do putStrLn "opening file" h <- openFile "test.txt" AppendMode putStrLn "opened file" - return h + pure h closeHandle :: Handle -> IO () closeHandle h = do @@ -65,7 +65,7 @@ server = writeToFile putStrLn "writing file" hPutStrLn h legalMsg putStrLn "wrote file" - return NoContent + pure NoContent ``` Finally we run the server in the background while we post messages to it. diff --git a/doc/cookbook/open-id-connect/OpenIdConnect.lhs b/doc/cookbook/open-id-connect/OpenIdConnect.lhs index 8f9fbc744..7b66a3906 100644 --- a/doc/cookbook/open-id-connect/OpenIdConnect.lhs +++ b/doc/cookbook/open-id-connect/OpenIdConnect.lhs @@ -122,7 +122,7 @@ api = Proxy server :: OIDCEnv -> Server API server oidcEnv = serveOIDC oidcEnv handleOIDCLogin - :<|> return Homepage + :<|> pure Homepage -- | Then main app app :: OIDCEnv -> Application @@ -161,7 +161,7 @@ initOIDC OIDCConf{..} = do mgr <- newManager tlsManagerSettings prov <- O.discover "https://accounts.google.com" mgr let oidc = O.setCredentials clientId clientPassword redirectUri (O.newOIDC prov) - return OIDCEnv { oidc = oidc + pure OIDCEnv { oidc = oidc , mgr = mgr , genState = genRandomBS , prov = prov @@ -208,13 +208,13 @@ genOIDCURL OIDCEnv{..} = do st <- genState -- generate a random string let oidcCreds = O.setCredentials clientId clientPassword redirectUri (O.newOIDC prov) loc <- O.getAuthenticationRequestUrl oidcCreds [O.openId, O.email, O.profile] (Just st) [] - return (show loc) + pure (show loc) handleLogin :: OIDCEnv -> Handler NoContent handleLogin oidcenv = do loc <- liftIO (genOIDCURL oidcenv) redirects loc - return NoContent + pure NoContent ``` The `AuthInfo` is about the infos we can grab from OIDC provider. @@ -236,7 +236,7 @@ instance FromJSON AuthInfo where email :: Text <- v .: "email" email_verified :: Bool <- v .: "email_verified" name :: Text <- v .: "name" - return $ AuthInfo (toS email) email_verified (toS name) + pure $ AuthInfo (toS email) email_verified (toS name) parseJSON invalid = AeT.typeMismatch "Coord" invalid instance JSON.ToJSON AuthInfo where toJSON (AuthInfo e ev n) = @@ -289,7 +289,7 @@ handleLoggedIn oidcenv handleSuccessfulId err mcode = if emailVerified authInfo then do user <- liftIO $ handleSuccessfulId authInfo - either forbidden return user + either forbidden pure user else forbidden "Please verify your email" Nothing -> do liftIO $ putText "No code param" @@ -371,7 +371,7 @@ We need some helpers to generate random string for generating state and API Keys genRandomBS :: IO ByteString genRandomBS = do g <- Random.newStdGen - Random.randomRs (0, n) g & take 42 & fmap toChar & readable 0 & toS & return + Random.randomRs (0, n) g & take 42 & fmap toChar & readable 0 & toS & pure where n = length letters - 1 toChar i = letters List.!! i @@ -394,7 +394,7 @@ genRandomBS = do customerFromAuthInfo :: AuthInfo -> IO Customer customerFromAuthInfo authinfo = do apikey <- genRandomBS - return Customer { account = toS (email authinfo) + pure Customer { account = toS (email authinfo) , apiKey = apikey , mail = Just (toS (email authinfo)) , fullname = Just (toS (name authinfo)) @@ -404,8 +404,8 @@ handleOIDCLogin :: LoginHandler handleOIDCLogin authInfo = do custInfo <- customerFromAuthInfo authInfo if emailVerified authInfo - then return . Right . customerToUser $ custInfo - else return (Left "You emails is not verified by your provider. Please verify your email.") + then pure . Right . customerToUser $ custInfo + else pure (Left "You emails is not verified by your provider. Please verify your email.") where customerToUser :: Customer -> User customerToUser c = diff --git a/doc/cookbook/sentry/Sentry.lhs b/doc/cookbook/sentry/Sentry.lhs index e2e41416d..0f9f8fd42 100644 --- a/doc/cookbook/sentry/Sentry.lhs +++ b/doc/cookbook/sentry/Sentry.lhs @@ -39,7 +39,7 @@ server = breakHandler where breakHandler :: Handler () breakHandler = do throw MyException - return () + pure () ``` First thing we need to do if we want to intercept and log this exception, we need to look in the section of our code where we run the `warp` application, and instead of using the simple `run` function from `warp`, we use the `runSettings` functions which allows to customise the handling of requests diff --git a/doc/cookbook/structuring-apis/StructuringApis.lhs b/doc/cookbook/structuring-apis/StructuringApis.lhs index 406147a5c..82375d974 100644 --- a/doc/cookbook/structuring-apis/StructuringApis.lhs +++ b/doc/cookbook/structuring-apis/StructuringApis.lhs @@ -81,10 +81,10 @@ type that `Server FactoringAPI` "resolves to" by typing factoringServer :: Server FactoringAPI factoringServer x = getXY :<|> postX - where getXY Nothing = return x - getXY (Just y) = return (x + y) + where getXY Nothing = pure x + getXY (Just y) = pure (x + y) - postX = return (x - 1) + postX = pure (x - 1) ``` If you want to avoid the "nested types" and the need to manually @@ -164,19 +164,19 @@ related sections of the API. ``` haskell userServer :: Server (SimpleAPI "users" User UserId) userServer = simpleServer - (return []) - (\userid -> return $ + (pure []) + (\userid -> pure $ if userid == 0 then User "john" 64 else User "everybody else" 10 ) - (\_user -> return NoContent) + (\_user -> pure NoContent) productServer :: Server (SimpleAPI "products" Product ProductId) productServer = simpleServer - (return []) - (\_productid -> return $ Product "Great stuff") - (\_product -> return NoContent) + (pure []) + (\_productid -> pure $ Product "Great stuff") + (\_product -> pure NoContent) ``` Finally, some dummy types and the serving part. diff --git a/doc/cookbook/testing/Testing.lhs b/doc/cookbook/testing/Testing.lhs index 1a7c61e72..5dec8ec62 100644 --- a/doc/cookbook/testing/Testing.lhs +++ b/doc/cookbook/testing/Testing.lhs @@ -407,9 +407,9 @@ api = Proxy server :: IO (Server API) server = do mvar <- newMVar "" - return $ (\x -> liftIO $ swapMVar mvar x) - :<|> (liftIO $ readMVar mvar >>= return . length) - :<|> (const $ return ()) + pure $ (\x -> liftIO $ swapMVar mvar x) + :<|> (liftIO $ readMVar mvar >>= pure . length) + :<|> (const $ pure ()) ``` ### Using `servant-quickcheck` @@ -427,7 +427,7 @@ args = defaultArgs { maxSuccess = 500 } -- Here's a Servant Context object we'll use ctx :: Context '[BasicAuthCheck ()] -ctx = BasicAuthCheck (const . return $ NoSuchUser) :. EmptyContext +ctx = BasicAuthCheck (const . pure $ NoSuchUser) :. EmptyContext servantQuickcheckSpec :: Spec diff --git a/doc/cookbook/using-custom-monad/UsingCustomMonad.lhs b/doc/cookbook/using-custom-monad/UsingCustomMonad.lhs index e03360656..aec4e14e1 100644 --- a/doc/cookbook/using-custom-monad/UsingCustomMonad.lhs +++ b/doc/cookbook/using-custom-monad/UsingCustomMonad.lhs @@ -69,7 +69,7 @@ server = getBooks :<|> addBook addBook book = do State{books = p} <- ask liftIO $ atomically $ readTVar p >>= writeTVar p . (book :) - return book + pure book ``` @@ -103,7 +103,7 @@ main = do _ <- printBooks _ <- addBookClient $ Book "The Picture of Dorian Gray" printBooks - return () + pure () ``` When run, it outputs the following: diff --git a/doc/cookbook/using-free-client/UsingFreeClient.lhs b/doc/cookbook/using-free-client/UsingFreeClient.lhs index 27893e3fe..80422456d 100644 --- a/doc/cookbook/using-free-client/UsingFreeClient.lhs +++ b/doc/cookbook/using-free-client/UsingFreeClient.lhs @@ -61,7 +61,7 @@ main = do case args of ("server":_) -> do putStrLn "Starting cookbook-using-free-client at http://localhost:8000" - run 8000 $ serve api $ \n -> return (n * n) + run 8000 $ serve api $ \n -> pure (n * n) ("client":_) -> test _ -> do diff --git a/doc/cookbook/uverb/UVerb.lhs b/doc/cookbook/uverb/UVerb.lhs index 70441194c..ebeafaa24 100644 --- a/doc/cookbook/uverb/UVerb.lhs +++ b/doc/cookbook/uverb/UVerb.lhs @@ -179,7 +179,7 @@ h = runUVerbT $ do -- a lot of code here... - return $ Foo 1 2 3 + pure $ Foo 1 2 3 ``` ## Related Work @@ -219,5 +219,5 @@ https://lukwagoallan.com/posts/unifying-servant-server-error-responses ```haskell main :: IO () -main = return () +main = pure () ``` diff --git a/doc/tutorial/Authentication.lhs b/doc/tutorial/Authentication.lhs index ded784d44..0cbd817c1 100644 --- a/doc/tutorial/Authentication.lhs +++ b/doc/tutorial/Authentication.lhs @@ -163,8 +163,8 @@ authCheck :: BasicAuthCheck User authCheck = let check (BasicAuthData username password) = if username == "servant" && password == "server" - then return (Authorized (User "servant")) - else return Unauthorized + then pure (Authorized (User "servant")) + else pure Unauthorized in BasicAuthCheck check ``` @@ -187,8 +187,8 @@ We're now ready to write our `server` method that will tie everything together: -- that takes 'User' as an argument. basicAuthServer :: Server BasicAPI basicAuthServer = - let publicAPIHandler = return [PublicData "foo", PublicData "bar"] - privateAPIHandler (user :: User) = return (PrivateData (userName user)) + let publicAPIHandler = pure [PublicData "foo", PublicData "bar"] + privateAPIHandler (user :: User) = pure (PrivateData (userName user)) in publicAPIHandler :<|> privateAPIHandler ``` @@ -278,7 +278,7 @@ database = fromList [ ("key1", Account "Anne Briggs") lookupAccount :: ByteString -> Handler Account lookupAccount key = case Map.lookup key database of Nothing -> throwError (err403 { errBody = "Invalid Cookie" }) - Just usr -> return usr + Just usr -> pure usr ``` For generalized authentication, servant exposes the `AuthHandler` type, @@ -350,8 +350,8 @@ genAuthServerContext = authHandler :. EmptyContext genAuthServer :: Server AuthGenAPI genAuthServer = let privateDataFunc (Account name) = - return (PrivateData ("this is a secret: " <> name)) - publicData = return [PublicData "this is a public piece of data"] + pure (PrivateData ("this is a secret: " <> name)) + publicData = pure [PublicData "this is a public piece of data"] in privateDataFunc :<|> publicData ``` diff --git a/doc/tutorial/Client.lhs b/doc/tutorial/Client.lhs index 35acee3d4..63a3eb539 100644 --- a/doc/tutorial/Client.lhs +++ b/doc/tutorial/Client.lhs @@ -134,7 +134,7 @@ queries = do pos <- position 10 10 message <- hello (Just "servant") em <- marketing (ClientInfo "Alp" "alp@foo.com" 26 ["haskell", "mathematics"]) - return (pos, message, em) + pure (pos, message, em) run :: IO () run = do @@ -223,7 +223,7 @@ Consider the following streaming API type: type StreamAPI = "positionStream" :> StreamGet NewlineFraming JSON (SourceIO Position) ``` -Note that we use the same `SourceIO` type as on the server-side +Note that we use the same `SourceIO` type as on the server-side (this is different from `servant-0.14`). However, we have to use different client, `Servant.Client.Streaming`, which can stream (but has different API). diff --git a/doc/tutorial/Javascript.lhs b/doc/tutorial/Javascript.lhs index 2ba6129f5..b51032575 100644 --- a/doc/tutorial/Javascript.lhs +++ b/doc/tutorial/Javascript.lhs @@ -99,8 +99,8 @@ following simple linear scan will do, given how small our list is. ``` haskell searchBook :: Monad m => Maybe Text -> m (Search Book) -searchBook Nothing = return (mkSearch "" books) -searchBook (Just q) = return (mkSearch q books') +searchBook Nothing = pure (mkSearch "" books) +searchBook (Just q) = pure (mkSearch q books') where books' = filter (\b -> q' `T.isInfixOf` T.toLower (author b) || q' `T.isInfixOf` T.toLower (title b) diff --git a/doc/tutorial/Server.lhs b/doc/tutorial/Server.lhs index 837113363..e525e633c 100644 --- a/doc/tutorial/Server.lhs +++ b/doc/tutorial/Server.lhs @@ -111,11 +111,11 @@ easily, as explained near the end of this guide. Third thing, the type of the value returned in that monad must be the same as the second argument of the HTTP method combinator used for the corresponding endpoint. In our case, it means we must provide a handler of type `Handler [User]`. Well, -we have a monad, let's just `return` our list: +we have a monad, let's just return our list: ``` haskell server1 :: Server UserAPI1 -server1 = return users1 +server1 = pure users1 ``` That's it. Now we can turn `server` into an actual webserver using @@ -186,9 +186,9 @@ the same order as in the API type. ``` haskell server2 :: Server UserAPI2 -server2 = return users2 - :<|> return albert - :<|> return isaac +server2 = pure users2 + :<|> pure albert + :<|> pure isaac ``` And that's it! You can run this example in the same way that we showed for @@ -265,15 +265,15 @@ server3 = position :<|> marketing where position :: Int -> Int -> Handler Position - position x y = return (Position x y) + position x y = pure (Position x y) hello :: Maybe String -> Handler HelloMessage - hello mname = return . HelloMessage $ case mname of + hello mname = pure . HelloMessage $ case mname of Nothing -> "Hello, anonymous coward" Just n -> "Hello, " ++ n marketing :: ClientInfo -> Handler Email - marketing clientinfo = return (emailForClient clientinfo) + marketing clientinfo = pure (emailForClient clientinfo) ``` Did you see that? The types for your handlers changed to be just what we @@ -566,7 +566,7 @@ personAPI :: Proxy PersonAPI personAPI = Proxy server4 :: Server PersonAPI -server4 = return people +server4 = pure people app2 :: Application app2 = serve personAPI server4 @@ -589,7 +589,7 @@ At the heart of the handlers is the monad they run in, namely a newtype `Handler One might wonder: why this monad? The answer is that it is the simplest monad with the following properties: -- it lets us both return a successful result (using `return`) +- it lets us both return a successful result (using `pure`/`return`) or "fail" with a descriptive error (using `throwError`); - it lets us perform IO, which is absolutely vital since most webservices exist as interfaces to databases that we interact with in `IO`. @@ -608,7 +608,7 @@ action that either returns an error or a result. The module [`Control.Monad.Except`](https://hackage.haskell.org/package/mtl/docs/Control-Monad-Except.html#t:ExceptT) from which `ExceptT` comes is worth looking at. Perhaps most importantly, `ExceptT` and `Handler` are instances of `MonadError`, so -`throwError` can be used to return an error from your handler (whereas `return` +`throwError` can be used to return an error from your handler (whereas `pure`/`return` is enough to return a success). Most of what you'll be doing in your handlers is running some IO and, @@ -642,7 +642,7 @@ instance ToJSON FileContent server5 :: Server IOAPI1 server5 = do filecontent <- liftIO (readFile "myfile.txt") - return (FileContent filecontent) + pure (FileContent filecontent) ``` ### Failing, through `ServerError` @@ -682,7 +682,7 @@ server6 :: Server IOAPI1 server6 = do exists <- liftIO (doesFileExist "myfile.txt") if exists - then liftIO (readFile "myfile.txt") >>= return . FileContent + then liftIO (readFile "myfile.txt") >>= pure . FileContent else throwError custom404Err where custom404Err = err404 { errBody = "myfile.txt just isn't there, please leave this server alone." } @@ -730,7 +730,7 @@ Note that this changes the type of your API, as we can see in the following exam type MyHandler = Get '[JSON] (Headers '[Header "X-An-Int" Int] User) myHandler :: Server MyHandler -myHandler = return $ addHeader 1797 albert +myHandler = pure $ addHeader 1797 albert ``` Note that the type of `addHeader header x` is different than the type of `x`! @@ -740,7 +740,7 @@ And if you add more headers, more headers will appear in the header list: type MyHeadfulHandler = Get '[JSON] (Headers '[Header "X-A-Bool" Bool, Header "X-An-Int" Int] User) myHeadfulHandler :: Server MyHeadfulHandler -myHeadfulHandler = return $ addHeader True $ addHeader 1797 albert +myHeadfulHandler = pure $ addHeader True $ addHeader 1797 albert ``` But what if your handler only *sometimes* adds a header? If you declare that @@ -753,7 +753,7 @@ type MyMaybeHeaderHandler = Capture "withHeader" Bool :> Get '[JSON] (Headers '[Header "X-An-Int" Int] User) myMaybeHeaderHandler :: Server MyMaybeHeaderHandler -myMaybeHeaderHandler x = return $ if x then addHeader 1797 albert +myMaybeHeaderHandler x = pure $ if x then addHeader 1797 albert else noHeader albert ``` @@ -1060,12 +1060,12 @@ readerToHandler :: Reader String a -> Handler a ``` We obviously have to run the `Reader` computation by supplying it with a -`String`, like `"hi"`. We get an `a` out from that and can then just `return` -it into `Handler`. +`String`, like `"hi"`. We get an `a` out from that and can then just lift it +it into `Handler` using `pure`. ``` haskell readerToHandler :: Reader String a -> Handler a -readerToHandler r = return (runReader r "hi") +readerToHandler r = pure (runReader r "hi") ``` We can write some simple webservice with the handlers running in `Reader String`. @@ -1080,7 +1080,7 @@ readerAPI = Proxy readerServerT :: ServerT ReaderAPI (Reader String) readerServerT = a :<|> b where a :: Reader String Int - a = return 1797 + a = pure 1797 b :: Double -> Reader String Bool b _ = asks (== "hi") @@ -1138,7 +1138,7 @@ funServerT = a :<|> b where b _ s = s == "hi" funToHandler :: (String -> a) -> Handler a -funToHandler f = return (f "hi") +funToHandler f = pure (f "hi") app5 :: Application app5 = serve readerAPI (hoistServer readerAPI funToHandler funServerT) @@ -1166,7 +1166,7 @@ streamUsers :: SourceIO User streamUsers = source [isaac, albert, albert] app6 :: Application -app6 = serve streamAPI (return streamUsers) +app6 = serve streamAPI (pure streamUsers) ``` This simple application returns a stream of `User` values encoded in JSON diff --git a/doc/tutorial/test/JavascriptSpec.hs b/doc/tutorial/test/JavascriptSpec.hs index 8383136e3..99c27fc1d 100644 --- a/doc/tutorial/test/JavascriptSpec.hs +++ b/doc/tutorial/test/JavascriptSpec.hs @@ -24,10 +24,10 @@ spec = do it "[not a test] write apiJS to static/api.js" $ do writeJSFiles - describe "app" $ with (return app) $ do + describe "app" $ with (pure app) $ do context "/api.js" $ do it "delivers apiJS" $ do - get "/api.js" `shouldRespondWith` (fromString (cs apiJS1)) + get "/api.js" `shouldRespondWith` fromString (cs apiJS1) context "/" $ do it "delivers something" $ do diff --git a/servant-auth/servant-auth-client/test/Servant/Auth/ClientSpec.hs b/servant-auth/servant-auth-client/test/Servant/Auth/ClientSpec.hs index ca3042cef..f30a68a2a 100644 --- a/servant-auth/servant-auth-client/test/Servant/Auth/ClientSpec.hs +++ b/servant-auth/servant-auth-client/test/Servant/Auth/ClientSpec.hs @@ -1,5 +1,4 @@ {-# LANGUAGE CPP #-} -{-# LANGUAGE DeriveAnyClass #-} module Servant.Auth.ClientSpec (spec) where @@ -56,11 +55,11 @@ spec = describe "The JWT combinator" $ do -- * HasClient {{{ hasClientSpec :: Spec -hasClientSpec = describe "HasClient" $ aroundAll (testWithApplication $ return app) $ do +hasClientSpec = describe "HasClient" $ aroundAll (testWithApplication $ pure app) $ do let mkTok :: User -> Maybe UTCTime -> IO Token mkTok user mexp = do Right tok <- makeJWT user jwtCfg mexp - return $ Token $ BSL.toStrict tok + pure $ Token $ BSL.toStrict tok it "succeeds when the token does not have expiry" $ \port -> property $ \user -> do tok <- mkTok user Nothing @@ -130,7 +129,7 @@ server :: Server API server = getInt where getInt :: AuthResult User -> Handler Int - getInt (Authenticated u) = return . length $ name u + getInt (Authenticated u) = pure . length $ name u getInt _ = throwAll err401 -- }}} diff --git a/servant-auth/servant-auth-server/README.lhs b/servant-auth/servant-auth-server/README.lhs index 272594659..d5857322c 100644 --- a/servant-auth/servant-auth-server/README.lhs +++ b/servant-auth/servant-auth-server/README.lhs @@ -80,7 +80,7 @@ type Protected protected :: Servant.Auth.Server.AuthResult User -> Server Protected -- If we get an "Authenticated v", we can trust the information in v, since -- it was signed by a key we trust. -protected (Servant.Auth.Server.Authenticated user) = return (name user) :<|> return (email user) +protected (Servant.Auth.Server.Authenticated user) = pure (name user) :<|> pure (email user) -- Otherwise, we return a 401. protected _ = throwAll err401 @@ -231,7 +231,7 @@ checkCreds cookieSettings jwtSettings (Login "Ali Baba" "Open Sesame") = do mApplyCookies <- liftIO $ acceptLogin cookieSettings jwtSettings usr case mApplyCookies of Nothing -> throwError err401 - Just applyCookies -> return $ applyCookies NoContent + Just applyCookies -> pure $ applyCookies NoContent checkCreds _ _ _ = throwError err401 ~~~ diff --git a/servant-auth/servant-auth-server/src/Servant/Auth/Server/Internal.hs b/servant-auth/servant-auth-server/src/Servant/Auth/Server/Internal.hs index 7acd90901..1044f69bb 100644 --- a/servant-auth/servant-auth-server/src/Servant/Auth/Server/Internal.hs +++ b/servant-auth/servant-auth-server/src/Servant/Auth/Server/Internal.hs @@ -48,7 +48,7 @@ instance authCheck = withRequest $ \req -> liftIO $ do authResult <- runAuthCheck (runAuths (Proxy :: Proxy auths) context) req cookies <- makeCookies authResult - return (authResult, cookies) + pure (authResult, cookies) jwtSettings :: JWTSettings jwtSettings = getContextEntry context @@ -62,8 +62,8 @@ instance (Authenticated v) -> do ejwt <- makeSessionCookie cookieSettings jwtSettings v xsrf <- makeXsrfCookie cookieSettings - return $ Just xsrf `SetCookieCons` (ejwt `SetCookieCons` SetCookieNil) - _ -> return $ Nothing `SetCookieCons` (Nothing `SetCookieCons` SetCookieNil) + pure $ Just xsrf `SetCookieCons` (ejwt `SetCookieCons` SetCookieNil) + _ -> pure $ Nothing `SetCookieCons` (Nothing `SetCookieCons` SetCookieNil) go :: (AuthResult v -> ServerT api Handler) diff --git a/servant-auth/servant-auth-server/src/Servant/Auth/Server/Internal/BasicAuth.hs b/servant-auth/servant-auth-server/src/Servant/Auth/Server/Internal/BasicAuth.hs index d37872210..0ef9503f3 100644 --- a/servant-auth/servant-auth-server/src/Servant/Auth/Server/Internal/BasicAuth.hs +++ b/servant-auth/servant-auth-server/src/Servant/Auth/Server/Internal/BasicAuth.hs @@ -54,5 +54,5 @@ class FromBasicAuthData a where basicAuthCheck :: FromBasicAuthData usr => BasicAuthCfg -> AuthCheck usr basicAuthCheck cfg = AuthCheck $ \req -> case decodeBAHdr req of - Nothing -> return Indefinite + Nothing -> pure Indefinite Just baData -> fromBasicAuthData baData cfg diff --git a/servant-auth/servant-auth-server/src/Servant/Auth/Server/Internal/Cookie.hs b/servant-auth/servant-auth-server/src/Servant/Auth/Server/Internal/Cookie.hs index f043e2e1c..161480cd4 100644 --- a/servant-auth/servant-auth-server/src/Servant/Auth/Server/Internal/Cookie.hs +++ b/servant-auth/servant-auth-server/src/Servant/Auth/Server/Internal/Cookie.hs @@ -29,42 +29,40 @@ import Servant.Auth.Server.Internal.Types cookieAuthCheck :: FromJWT usr => CookieSettings -> JWTSettings -> AuthCheck usr cookieAuthCheck ccfg jwtSettings = do req <- ask - jwtCookie <- maybe mempty return $ do + jwtCookie <- maybe mempty pure $ do cookies' <- lookup hCookie $ requestHeaders req let cookies = parseCookies cookies' -- Apply the XSRF check if enabled. guard $ fromMaybe True $ do xsrfCookieCfg <- xsrfCheckRequired ccfg req - return $ xsrfCookieAuthCheck xsrfCookieCfg req cookies + pure $ xsrfCookieAuthCheck xsrfCookieCfg req cookies -- session cookie *must* be HttpOnly and Secure lookup (sessionCookieName ccfg) cookies verifiedJWT <- liftIO $ verifyJWT jwtSettings jwtCookie - case verifiedJWT of - Nothing -> mzero - Just v -> return v + maybe mzero pure verifiedJWT xsrfCheckRequired :: CookieSettings -> Request -> Maybe XsrfCookieSettings xsrfCheckRequired cookieSettings req = do xsrfCookieCfg <- cookieXsrfSetting cookieSettings let disableForGetReq = xsrfExcludeGet xsrfCookieCfg && requestMethod req == methodGet guard $ not disableForGetReq - return xsrfCookieCfg + pure xsrfCookieCfg xsrfCookieAuthCheck :: XsrfCookieSettings -> Request -> [(BS.ByteString, BS.ByteString)] -> Bool xsrfCookieAuthCheck xsrfCookieCfg req cookies = fromMaybe False $ do xsrfCookie <- lookup (xsrfCookieName xsrfCookieCfg) cookies xsrfHeader <- lookup (mk $ xsrfHeaderName xsrfCookieCfg) $ requestHeaders req - return $ xsrfCookie `constEq` xsrfHeader + pure $ xsrfCookie `constEq` xsrfHeader -- | Makes a cookie to be used for XSRF. makeXsrfCookie :: CookieSettings -> IO SetCookie makeXsrfCookie cookieSettings = case cookieXsrfSetting cookieSettings of Just xsrfCookieSettings -> makeRealCookie xsrfCookieSettings - Nothing -> return $ noXsrfTokenCookie cookieSettings + Nothing -> pure $ noXsrfTokenCookie cookieSettings where makeRealCookie xsrfCookieSettings = do xsrfValue <- BS64.encode <$> getEntropy 32 - return $ + pure $ applyXsrfCookieSettings xsrfCookieSettings $ applyCookieSettings cookieSettings $ def{setCookieValue = xsrfValue} @@ -79,9 +77,9 @@ makeSessionCookie :: ToJWT v => CookieSettings -> JWTSettings -> v -> IO (Maybe makeSessionCookie cookieSettings jwtSettings v = do ejwt <- makeJWT v jwtSettings (cookieExpires cookieSettings) case ejwt of - Left _ -> return Nothing + Left _ -> pure Nothing Right jwt -> - return $ + pure $ Just $ applySessionCookieSettings cookieSettings $ applyCookieSettings cookieSettings $ @@ -146,7 +144,7 @@ acceptLogin cookieSettings jwtSettings session = do Nothing -> pure Nothing Just sessionCookie -> do xsrfCookie <- makeXsrfCookie cookieSettings - return $ Just $ addHeader' sessionCookie . addHeader' xsrfCookie + pure $ Just $ addHeader' sessionCookie . addHeader' xsrfCookie -- | Arbitrary cookie expiry time set back in history after unix time 0 expireTime :: UTCTime diff --git a/servant-auth/servant-auth-server/src/Servant/Auth/Server/Internal/JWT.hs b/servant-auth/servant-auth-server/src/Servant/Auth/Server/Internal/JWT.hs index a84296e57..ea07866ac 100644 --- a/servant-auth/servant-auth-server/src/Servant/Auth/Server/Internal/JWT.hs +++ b/servant-auth/servant-auth-server/src/Servant/Auth/Server/Internal/JWT.hs @@ -21,16 +21,14 @@ import Servant.Auth.Server.Internal.Types jwtAuthCheck :: FromJWT usr => JWTSettings -> AuthCheck usr jwtAuthCheck jwtSettings = do req <- ask - token <- maybe mempty return $ do + token <- maybe mempty pure $ do authHdr <- lookup "Authorization" $ requestHeaders req let bearer = "Bearer " (mbearer, rest) = BS.splitAt (BS.length bearer) authHdr guard (mbearer `constEq` bearer) - return rest + pure rest verifiedJWT <- liftIO $ verifyJWT jwtSettings token - case verifiedJWT of - Nothing -> mzero - Just v -> return v + maybe mzero pure verifiedJWT -- | Creates a JWT containing the specified data. The data is stored in the -- @dat@ claim. The 'Maybe UTCTime' argument indicates the time at which the @@ -50,7 +48,7 @@ makeJWT v cfg expiry = Jose.runJOSE $ do (Jose.newJWSHeader ((), alg)) (addExp $ encodeJWT v) - return $ Jose.encodeCompact ejwt + pure $ Jose.encodeCompact ejwt where addExp claims = case expiry of Nothing -> claims @@ -65,7 +63,7 @@ verifyJWT jwtCfg input = do (jwtSettingsToJwtValidationSettings jwtCfg) keys unverifiedJWT - return $ case verifiedJWT of + pure $ case verifiedJWT of Left (_ :: Jose.JWTError) -> Nothing Right v -> case decodeJWT v of Left _ -> Nothing diff --git a/servant-auth/servant-auth-server/src/Servant/Auth/Server/Internal/Types.hs b/servant-auth/servant-auth-server/src/Servant/Auth/Server/Internal/Types.hs index 5b30611e4..5a97a67ec 100644 --- a/servant-auth/servant-auth-server/src/Servant/Auth/Server/Internal/Types.hs +++ b/servant-auth/servant-auth-server/src/Servant/Auth/Server/Internal/Types.hs @@ -35,11 +35,10 @@ instance Monoid (AuthResult val) where mappend = (<>) instance Applicative AuthResult where - pure = return + pure = Authenticated (<*>) = ap instance Monad AuthResult where - return = Authenticated Authenticated v >>= f = f v BadPassword >>= _ = BadPassword NoSuchUser >>= _ = NoSuchUser @@ -69,32 +68,31 @@ instance Semigroup (AuthCheck val) where r -> pure r instance Monoid (AuthCheck val) where - mempty = AuthCheck $ const $ return mempty + mempty = AuthCheck $ const $ pure mempty mappend = (<>) instance Applicative AuthCheck where - pure = return + pure = AuthCheck . pure . pure . pure (<*>) = ap instance Monad AuthCheck where - return = AuthCheck . return . return . return AuthCheck ac >>= f = AuthCheck $ \req -> do aresult <- ac req case aresult of Authenticated usr -> runAuthCheck (f usr) req - BadPassword -> return BadPassword - NoSuchUser -> return NoSuchUser - Indefinite -> return Indefinite + BadPassword -> pure BadPassword + NoSuchUser -> pure NoSuchUser + Indefinite -> pure Indefinite #if !MIN_VERSION_base(4,13,0) fail = Fail.fail #endif instance Fail.MonadFail AuthCheck where - fail _ = AuthCheck . const $ return Indefinite + fail _ = AuthCheck . const $ pure Indefinite instance MonadReader Request AuthCheck where - ask = AuthCheck $ \x -> return (Authenticated x) + ask = AuthCheck $ \x -> pure (Authenticated x) local f (AuthCheck check) = AuthCheck $ \req -> check (f req) instance MonadIO AuthCheck where diff --git a/servant-auth/servant-auth-server/test/Servant/Auth/ServerSpec.hs b/servant-auth/servant-auth-server/test/Servant/Auth/ServerSpec.hs index 6b783e282..3cdb56109 100644 --- a/servant-auth/servant-auth-server/test/Servant/Auth/ServerSpec.hs +++ b/servant-auth/servant-auth-server/test/Servant/Auth/ServerSpec.hs @@ -1,4 +1,5 @@ {-# LANGUAGE CPP #-} +{-# LANGUAGE LambdaCase #-} {-# LANGUAGE TypeApplications #-} module Servant.Auth.ServerSpec (spec) where @@ -8,6 +9,7 @@ module Servant.Auth.ServerSpec (spec) where #endif import Control.Lens +import Control.Monad (forM_) import Control.Monad.IO.Class (liftIO) import Crypto.JOSE ( Alg (HS256, None) @@ -38,10 +40,8 @@ import qualified Data.ByteString as BS import qualified Data.ByteString.Lazy as BSL import Data.CaseInsensitive (mk) import Data.Foldable (find) -import Data.Monoid import Data.Text (Text, pack) import Data.Time -import Data.Time.Clock (getCurrentTime) import GHC.Generics (Generic) import Network.HTTP.Client ( cookie_expiry_time @@ -101,7 +101,7 @@ spec = do authSpec :: Spec authSpec = describe "The Auth combinator" $ - aroundAll (testWithApplication . return $ app jwtAndCookieApi) $ do + aroundAll (testWithApplication . pure $ app jwtAndCookieApi) $ do it "returns a 401 if all authentications are Indefinite" $ \port -> do get (url port) `shouldHTTPErrorWith` status401 @@ -158,7 +158,7 @@ authSpec = destroyCookieJar cookieJar opts2 = defaults - & cookies .~ Just cookieJar + & cookies ?~ cookieJar & header (mk (xsrfField xsrfHeaderName cookieCfg)) .~ [cookie_value xxsrf] resp2 <- getWith opts2 (url port) resp2 ^? responseBody . _JSON `shouldBe` Just (length $ name user) @@ -208,7 +208,7 @@ cookieAuthSpec :: Spec cookieAuthSpec = describe "The Auth combinator" $ do describe "With XSRF check" $ - aroundAll (testWithApplication . return $ app cookieOnlyApi) $ do + aroundAll (testWithApplication . pure $ app cookieOnlyApi) $ do it "fails if XSRF header and cookie don't match" $ \port -> property $ \(user :: User) -> do jwt <- createJWT theKey (newJWSHeader ((), HS256)) (claims $ toJSON user) @@ -223,7 +223,7 @@ cookieAuthSpec = \(user :: User) -> do jwt <- createJWT theKey (newJWSHeader ((), HS256)) (claims $ toJSON user) opts' <- addJwtToCookie cookieCfg jwt - let opts = opts' & checkResponse .~ Just mempty + let opts = opts' & checkResponse ?~ mempty resp <- getWith opts (url port) resp ^. responseStatus `shouldBe` status401 (resp ^. responseCookieJar) `shouldNotHaveCookies` ["XSRF-TOKEN"] @@ -254,7 +254,7 @@ cookieAuthSpec = let jar = resp ^. responseCookieJar Just xsrfCookieValue = cookie_value <$> find (\c -> cookie_name c == xsrfField xsrfCookieName cookieCfg) (destroyCookieJar jar) in defaults - & cookies .~ Just jar -- real cookie jars aren't updated by being replaced + & cookies ?~ jar -- real cookie jars aren't updated by being replaced & header (mk (xsrfField xsrfHeaderName cookieCfg)) .~ [xsrfCookieValue] resp <- postWith defaults (url port ++ "/login") user @@ -281,9 +281,9 @@ cookieAuthSpec = describe "With no XSRF check for GET requests" $ let noXsrfGet xsrfCfg = xsrfCfg{xsrfExcludeGet = True} - cookieCfgNoXsrfGet = cookieCfg{cookieXsrfSetting = fmap noXsrfGet $ cookieXsrfSetting cookieCfg} + cookieCfgNoXsrfGet = cookieCfg{cookieXsrfSetting = noXsrfGet <$> cookieXsrfSetting cookieCfg} in - aroundAll (testWithApplication . return $ appWithCookie cookieOnlyApi cookieCfgNoXsrfGet) $ do + aroundAll (testWithApplication . pure $ appWithCookie cookieOnlyApi cookieCfgNoXsrfGet) $ do it "succeeds with no XSRF header or cookie for GET" $ \port -> property $ \(user :: User) -> do jwt <- createJWT theKey (newJWSHeader ((), HS256)) (claims $ toJSON user) @@ -301,7 +301,7 @@ cookieAuthSpec = let cookieCfgNoXsrf = cookieCfg{cookieXsrfSetting = Nothing} in - aroundAll (testWithApplication . return $ appWithCookie cookieOnlyApi cookieCfgNoXsrf) $ do + aroundAll (testWithApplication . pure $ appWithCookie cookieOnlyApi cookieCfgNoXsrf) $ do it "succeeds with no XSRF header or cookie for GET" $ \port -> property $ \(user :: User) -> do jwt <- createJWT theKey (newJWSHeader ((), HS256)) (claims $ toJSON user) @@ -320,7 +320,7 @@ cookieAuthSpec = \(user :: User) -> do let optsFromResp resp = defaults - & cookies .~ Just (resp ^. responseCookieJar) -- real cookie jars aren't updated by being replaced + & cookies ?~ (resp ^. responseCookieJar) -- real cookie jars aren't updated by being replaced resp <- postWith defaults (url port ++ "/login") user (resp ^. responseCookieJar) `shouldMatchCookieNames` [ sessionCookieName cookieCfg @@ -328,7 +328,7 @@ cookieAuthSpec = ] let loggedInOpts = optsFromResp resp - resp <- getWith (loggedInOpts) (url port) + resp <- getWith loggedInOpts (url port) resp ^? responseBody . _JSON `shouldBe` Just (length $ name user) resp <- getWith loggedInOpts (url port ++ "/logout") @@ -354,15 +354,15 @@ cookieAuthSpec = jwtAuthSpec :: Spec jwtAuthSpec = describe "The JWT combinator" $ - aroundAll (testWithApplication . return $ app jwtOnlyApi) $ do + aroundAll (testWithApplication . pure $ app jwtOnlyApi) $ do it "fails if 'aud' does not match predicate" $ \port -> property $ \(user :: User) -> do jwt <- createJWT theKey (newJWSHeader ((), HS256)) - (claims (toJSON user) & claimAud .~ Just (Audience ["boo"])) - opts <- addJwtToHeader (jwt >>= (return . encodeCompact)) + (claims (toJSON user) & claimAud ?~ Audience ["boo"]) + opts <- addJwtToHeader (jwt <&> encodeCompact) getWith opts (url port) `shouldHTTPErrorWith` status401 it "succeeds if 'aud' does match predicate" $ \port -> property $ @@ -371,8 +371,8 @@ jwtAuthSpec = createJWT theKey (newJWSHeader ((), HS256)) - (claims (toJSON user) & claimAud .~ Just (Audience ["anythingElse"])) - opts <- addJwtToHeader (jwt >>= (return . encodeCompact)) + (claims (toJSON user) & claimAud ?~ Audience ["anythingElse"]) + opts <- addJwtToHeader (jwt <&> encodeCompact) resp <- getWith opts (url port) resp ^. responseStatus `shouldBe` status200 @@ -382,8 +382,8 @@ jwtAuthSpec = createJWT theKey (newJWSHeader ((), HS256)) - (claims (toJSON user) & claimNbf .~ Just (NumericDate future)) - opts <- addJwtToHeader (jwt >>= (return . encodeCompact)) + (claims (toJSON user) & claimNbf ?~ NumericDate future) + opts <- addJwtToHeader (jwt <&> encodeCompact) getWith opts (url port) `shouldHTTPErrorWith` status401 it "fails if 'exp' is set to a past date" $ \port -> property $ @@ -405,7 +405,7 @@ jwtAuthSpec = theKey (newJWSHeader ((), None)) (claims $ toJSON user) - opts <- addJwtToHeader (jwt >>= (return . encodeCompact)) + opts <- addJwtToHeader (jwt <&> encodeCompact) getWith opts (url port) `shouldHTTPErrorWith` status401 it "fails if JWT does not use expected algorithm" $ @@ -414,7 +414,7 @@ jwtAuthSpec = it "fails if data is not valid JSON" $ \port -> do jwt <- createJWT theKey (newJWSHeader ((), HS256)) (claims "{{") - opts <- addJwtToHeader (jwt >>= (return . encodeCompact)) + opts <- addJwtToHeader (jwt <&> encodeCompact) getWith opts (url port) `shouldHTTPErrorWith` status401 it "suceeds as wreq's oauth2Bearer" $ \port -> property $ \(user :: User) -> do @@ -423,7 +423,7 @@ jwtAuthSpec = theKey (newJWSHeader ((), HS256)) (claims $ toJSON user) - resp <- case jwt >>= (return . encodeCompact) of + resp <- case jwt <&> encodeCompact of Left (e :: Error) -> fail $ show e Right v -> getWith (defaults & auth ?~ oauth2Bearer (BSL.toStrict v)) (url port) resp ^. responseStatus `shouldBe` status200 @@ -435,7 +435,7 @@ jwtAuthSpec = basicAuthSpec :: Spec basicAuthSpec = describe "The BasicAuth combinator" $ - aroundAll (testWithApplication . return $ app basicAuthApi) $ do + aroundAll (testWithApplication . pure $ app basicAuthApi) $ do it "succeeds with the correct password and username" $ \port -> do resp <- getWith (defaults & auth ?~ basicAuth "ali" "Open sesame") (url port) resp ^. responseStatus `shouldBe` status200 @@ -493,7 +493,7 @@ type API auths , Header "Set-Cookie" SetCookie ] NoContent) {- FOURMOLU_ENABLE -} -data DummyRoutes mode = DummyRoutes +newtype DummyRoutes mode = DummyRoutes { dummyInt :: mode :- "dummy" :> Get '[JSON] Int } deriving (Generic) @@ -540,7 +540,7 @@ jwtCfg = instance FromBasicAuthData User where fromBasicAuthData (BasicAuthData usr pwd) _ = - return $ + pure $ if usr == "ali" && pwd == "Open sesame" then Authenticated $ User "ali" "ali@the-thieves-den.com" else Indefinite @@ -566,22 +566,23 @@ app app api = appWithCookie api cookieCfg {- FOURMOLU_DISABLE -} + server :: CookieSettings -> Server (API auths) server ccfg = - ( \authResult -> case authResult of + ( \case Authenticated usr -> getInt usr :<|> postInt usr :<|> DummyRoutes{dummyInt = getInt usr} :<|> getHeaderInt #if MIN_VERSION_servant_server(0,15,0) - :<|> return (S.source ["bytestring"]) + :<|> pure (S.source ["bytestring"]) #endif :<|> raw Indefinite -> throwAll err401 _ -> throwAll err403 ) - :<|> ( \authResult -> case authResult of + :<|> ( \case Authenticated usr -> respond (WithStatus @200 (42 :: Int)) Indefinite -> respond (WithStatus @401 $ pack "Authentication required") _ -> respond (WithStatus @403 $ pack "Forbidden") @@ -590,13 +591,13 @@ server ccfg = :<|> getLogout where getInt :: User -> Handler Int - getInt usr = return . length $ name usr + getInt usr = pure . length $ name usr postInt :: User -> Int -> Handler Int - postInt _ = return + postInt _ = pure getHeaderInt :: Handler (Headers '[Header "Blah" Int] Int) - getHeaderInt = return $ addHeader 1797 17 + getHeaderInt = pure $ addHeader 1797 17 getLogin :: User @@ -610,7 +611,7 @@ server ccfg = getLogin user = do maybeApplyCookies <- liftIO $ acceptLogin ccfg jwtCfg user case maybeApplyCookies of - Just applyCookies -> return $ applyCookies NoContent + Just applyCookies -> pure $ applyCookies NoContent Nothing -> error "cookies failed to apply" getLogout @@ -621,15 +622,19 @@ server ccfg = ] NoContent ) - getLogout = return $ clearSession ccfg NoContent + getLogout = pure $ clearSession ccfg NoContent raw :: Server Raw - raw = + raw = tagged $ \_req respond -> + respond $ responseLBS status200 [("hi", "there")] "how are you?" + #if MIN_VERSION_servant_server(0,11,0) - Tagged $ + tagged :: Application -> Tagged Handler Application + tagged = Tagged +#else + tagged :: Application -> Application + tagged = id #endif - \_req respond -> - respond $ responseLBS status200 [("hi", "there")] "how are you?" {- FOURMOLU_ENABLE -} -- }}} @@ -644,33 +649,33 @@ future :: UTCTime future = parseTimeOrError True defaultTimeLocale "%Y-%m-%d" "2070-01-01" addJwtToHeader :: Either Error BSL.ByteString -> IO Options -addJwtToHeader jwt = case jwt of +addJwtToHeader = \case Left e -> fail $ show e Right v -> - return $ + pure $ defaults & header "Authorization" .~ ["Bearer " <> BSL.toStrict v] createJWT :: JWK -> JWSHeader () -> ClaimsSet -> IO (Either Error Crypto.JWT.SignedJWT) createJWT k a b = runJOSE $ signClaims k a b addJwtToCookie :: ToCompact a => CookieSettings -> Either Error a -> IO Options -addJwtToCookie ccfg jwt = case jwt >>= (return . encodeCompact) of +addJwtToCookie ccfg jwt = case jwt <&> encodeCompact of Left e -> fail $ show e Right v -> - return $ + pure $ defaults & header "Cookie" .~ [sessionCookieName ccfg <> "=" <> BSL.toStrict v] addCookie :: Options -> BS.ByteString -> Options addCookie opts cookie' = opts - & header "Cookie" %~ \c -> case c of + & header "Cookie" %~ \case [h] -> [cookie' <> "; " <> h] [] -> [cookie'] _ -> error "expecting single cookie header" {- FOURMOLU_DISABLE -} shouldHTTPErrorWith :: IO a -> Status -> Expectation -shouldHTTPErrorWith act stat = act `shouldThrow` \e -> case e of +shouldHTTPErrorWith act stat = act `shouldThrow` \case #if MIN_VERSION_http_client(0,5,0) HCli.HttpExceptionRequest _ (HCli.StatusCodeException resp _) -> HCli.responseStatus resp == stat @@ -687,7 +692,7 @@ shouldMatchCookieNames cj patterns = shouldNotHaveCookies :: HCli.CookieJar -> [BS.ByteString] -> Expectation shouldNotHaveCookies cj patterns = - sequence_ $ (\cookieName -> cookieNames `shouldNotContain` [cookieName]) <$> patterns + forM_ patterns (\cookieName -> cookieNames `shouldNotContain` [cookieName]) where cookieNames :: [BS.ByteString] cookieNames = cookie_name <$> destroyCookieJar cj @@ -701,7 +706,7 @@ url :: Int -> String url port = "http://localhost:" <> show port claims :: Value -> ClaimsSet -claims val = emptyClaimsSet & unregisteredClaims . at "dat" .~ Just val +claims val = emptyClaimsSet & unregisteredClaims . at "dat" ?~ val -- }}} ------------------------------------------------------------------------------ @@ -727,7 +732,7 @@ instance Arbitrary User where instance Postable User where postPayload user request = - return $ + pure $ request { HCli.requestBody = HCli.RequestBodyLBS $ encode user , HCli.requestHeaders = (mk "Content-Type", "application/json") : HCli.requestHeaders request diff --git a/servant-auth/servant-auth/src/Servant/Auth.hs b/servant-auth/servant-auth/src/Servant/Auth.hs index 638fe9044..763a191b3 100644 --- a/servant-auth/servant-auth/src/Servant/Auth.hs +++ b/servant-auth/servant-auth/src/Servant/Auth.hs @@ -1,6 +1,5 @@ {-# LANGUAGE CPP #-} {-# LANGUAGE DataKinds #-} -{-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeOperators #-} diff --git a/servant-client-core/src/Servant/Client/Core/BaseUrl.hs b/servant-client-core/src/Servant/Client/Core/BaseUrl.hs index 272b94bee..935952948 100644 --- a/servant-client-core/src/Servant/Client/Core/BaseUrl.hs +++ b/servant-client-core/src/Servant/Client/Core/BaseUrl.hs @@ -71,7 +71,7 @@ instance ToJSON BaseUrl where -- Just (BaseUrl {baseUrlScheme = Http, baseUrlHost = "api.example.com", baseUrlPort = 80, baseUrlPath = ""}) instance FromJSON BaseUrl where parseJSON = withText "BaseUrl" $ \t -> case parseBaseUrl (T.unpack t) of - Just u -> return u + Just u -> pure u Nothing -> fail $ "Invalid base url: " ++ T.unpack t -- | >>> :{ @@ -86,7 +86,7 @@ instance ToJSONKey BaseUrl where instance FromJSONKey BaseUrl where fromJSONKey = FromJSONKeyTextParser $ \t -> case parseBaseUrl (T.unpack t) of - Just u -> return u + Just u -> pure u Nothing -> fail $ "Invalid base url: " ++ T.unpack t -- | >>> showBaseUrl <$> parseBaseUrl "api.example.com" @@ -125,13 +125,13 @@ parseBaseUrl s = case parseURI (removeTrailingSlash s) of -- This is a rather hacky implementation and should be replaced with something -- implemented in attoparsec (which is already a dependency anyhow (via aeson)). Just (URI "http:" (Just (URIAuth "" host (':' : (readMaybe -> Just port)))) path "" "") -> - return (BaseUrl Http host port path) + pure (BaseUrl Http host port path) Just (URI "http:" (Just (URIAuth "" host "")) path "" "") -> - return (BaseUrl Http host 80 path) + pure (BaseUrl Http host 80 path) Just (URI "https:" (Just (URIAuth "" host (':' : (readMaybe -> Just port)))) path "" "") -> - return (BaseUrl Https host port path) + pure (BaseUrl Https host port path) Just (URI "https:" (Just (URIAuth "" host "")) path "" "") -> - return (BaseUrl Https host 443 path) + pure (BaseUrl Https host 443 path) _ -> if "://" `List.isInfixOf` s then throwM (InvalidBaseUrlException $ "Invalid base URL: " ++ s) diff --git a/servant-client-core/src/Servant/Client/Core/ClientError.hs b/servant-client-core/src/Servant/Client/Core/ClientError.hs index 47b14ba8a..8edaf2240 100644 --- a/servant-client-core/src/Servant/Client/Core/ClientError.hs +++ b/servant-client-core/src/Servant/Client/Core/ClientError.hs @@ -1,10 +1,6 @@ {-# LANGUAGE DeriveDataTypeable #-} -{-# LANGUAGE DeriveFoldable #-} -{-# LANGUAGE DeriveFunctor #-} {-# LANGUAGE DeriveGeneric #-} -{-# LANGUAGE DeriveTraversable #-} {-# LANGUAGE MultiParamTypeClasses #-} -{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE RankNTypes #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeFamilies #-} diff --git a/servant-client-core/src/Servant/Client/Core/HasClient.hs b/servant-client-core/src/Servant/Client/Core/HasClient.hs index 1459ac993..fba7b2dc5 100644 --- a/servant-client-core/src/Servant/Client/Core/HasClient.hs +++ b/servant-client-core/src/Servant/Client/Core/HasClient.hs @@ -257,8 +257,7 @@ instance where p = toEncodedUrlPiece val - hoistClientMonad pm _ f cl = \a -> - hoistClientMonad pm (Proxy :: Proxy api) f (cl a) + hoistClientMonad pm _ f cl = hoistClientMonad pm (Proxy :: Proxy api) f . cl -- | If you use a 'CaptureAll' in one of your endpoints in your API, -- the corresponding querying function will automatically take an @@ -296,8 +295,7 @@ instance where ps = map toEncodedUrlPiece vals - hoistClientMonad pm _ f cl = \as -> - hoistClientMonad pm (Proxy :: Proxy sublayout) f (cl as) + hoistClientMonad pm _ f cl = hoistClientMonad pm (Proxy :: Proxy sublayout) f . cl instance -- Note [Non-Empty Content Types] @@ -326,7 +324,7 @@ instance method = reflectMethod (Proxy :: Proxy method) status = statusFromNat (Proxy :: Proxy status) - hoistClientMonad _ _ f ma = f ma + hoistClientMonad _ _ f = f instance {-# OVERLAPPING #-} @@ -341,12 +339,12 @@ instance m NoContent clientWithRoute _pm Proxy req = do _response <- runRequestAcceptStatus (Just [status]) req{requestMethod = method} - return NoContent + pure NoContent where method = reflectMethod (Proxy :: Proxy method) status = statusFromNat (Proxy :: Proxy status) - hoistClientMonad _ _ f ma = f ma + hoistClientMonad _ _ f = f instance (ReflectMethod method, RunClient m) @@ -357,11 +355,11 @@ instance m NoContent clientWithRoute _pm Proxy req = do _response <- runRequest req{requestMethod = method} - return NoContent + pure NoContent where method = reflectMethod (Proxy :: Proxy method) - hoistClientMonad _ _ f ma = f ma + hoistClientMonad _ _ f = f instance -- Note [Non-Empty Content Types] @@ -388,7 +386,7 @@ instance , requestAccept = fromList $ toList accept } val <- response `decodedAs` (Proxy :: Proxy ct) - return $ + pure $ Headers { getResponse = val , getHeadersHList = buildHeadersTo . toList $ responseHeaders response @@ -398,7 +396,7 @@ instance accept = contentTypes (Proxy :: Proxy ct) status = statusFromNat (Proxy :: Proxy status) - hoistClientMonad _ _ f ma = f ma + hoistClientMonad _ _ f = f instance {-# OVERLAPPING #-} @@ -414,7 +412,7 @@ instance m (Headers ls NoContent) clientWithRoute _pm Proxy req = do response <- runRequestAcceptStatus (Just [status]) req{requestMethod = method} - return $ + pure $ Headers { getResponse = NoContent , getHeadersHList = buildHeadersTo . toList $ responseHeaders response @@ -423,7 +421,7 @@ instance method = reflectMethod (Proxy :: Proxy method) status = statusFromNat (Proxy :: Proxy status) - hoistClientMonad _ _ f ma = f ma + hoistClientMonad _ _ f = f data ClientParseError = ClientParseError MediaType String | ClientStatusMismatch | ClientNoMatchingStatus deriving (Eq, Show) @@ -438,7 +436,7 @@ class UnrenderResponse (cts :: [Type]) (a :: Type) where instance {-# OVERLAPPABLE #-} AllMimeUnrender cts a => UnrenderResponse cts a where unrenderResponse _ body = map parse . allMimeUnrender where - parse (mediaType, parser) = left ((,) mediaType) (parser body) + parse (mediaType, parser) = left (mediaType,) (parser body) instance {-# OVERLAPPING #-} @@ -494,7 +492,7 @@ instance let res = tryParsers status $ mimeUnrenders (Proxy @contentTypes) headers body case res of Left errors -> throwClientError $ DecodeFailure (T.pack (show errors)) response - Right x -> return x + Right x -> pure x where -- \| Given a list of parsers of 'mkres', returns the first one that succeeds and all the -- failures it encountered along the way @@ -505,7 +503,7 @@ instance | status == statusOf (Comp x) = case partitionEithers x of (err', []) -> (map (uncurry ClientParseError) err' ++) +++ S $ tryParsers status xs - (_, (res : _)) -> Right . inject . I $ res + (_, res : _) -> Right . inject . I $ res | otherwise -- no reason to parse in the first place. This ain't the one we're looking for = (ClientStatusMismatch :) +++ S $ tryParsers status xs @@ -523,7 +521,7 @@ instance (Proxy @(UnrenderResponse cts)) (Comp . unrenderResponse headers body $ ctp) - hoistClientMonad _ _ nt s = nt s + hoistClientMonad _ _ nt = nt instance {-# OVERLAPPABLE #-} @@ -537,7 +535,7 @@ instance where type Client m (Stream method status framing ct a) = m a - hoistClientMonad _ _ f ma = f ma + hoistClientMonad _ _ f = f clientWithRoute _pm Proxy req = withStreamingRequest req' $ \Response{responseBody = body} -> do let mimeUnrender' = mimeUnrender (Proxy :: Proxy ct) :: BSL.ByteString -> Either String chunk @@ -563,14 +561,14 @@ instance where type Client m (Stream method status framing ct (Headers hs a)) = m (Headers hs a) - hoistClientMonad _ _ f ma = f ma + hoistClientMonad _ _ f = f clientWithRoute _pm Proxy req = withStreamingRequest req' $ \Response{responseBody = body, responseHeaders = headers} -> do let mimeUnrender' = mimeUnrender (Proxy :: Proxy ct) :: BSL.ByteString -> Either String chunk framingUnrender' = framingUnrender (Proxy :: Proxy framing) mimeUnrender' val <- fromSourceIO $ framingUnrender' body - return $ + pure $ Headers { getResponse = val , getHeadersHList = buildHeadersTo $ toList headers @@ -691,8 +689,7 @@ instance add :: a -> Request add value = addHeader hname value req - hoistClientMonad pm _ f cl = \arg -> - hoistClientMonad pm (Proxy :: Proxy api) f (cl arg) + hoistClientMonad pm _ f cl = hoistClientMonad pm (Proxy :: Proxy api) f . cl instance (HasClient m api, KnownSymbol sym) => HasClient m (Host sym :> api) where type Client m (Host sym :> api) = Client m api @@ -716,7 +713,7 @@ instance clientWithRoute pm Proxy = clientWithRoute pm (Proxy :: Proxy api) - hoistClientMonad pm _ f cl = hoistClientMonad pm (Proxy :: Proxy api) f cl + hoistClientMonad pm _ = hoistClientMonad pm (Proxy :: Proxy api) -- | Ignore @'Summary'@ in client functions. instance HasClient m api => HasClient m (Summary desc :> api) where @@ -724,7 +721,7 @@ instance HasClient m api => HasClient m (Summary desc :> api) where clientWithRoute pm _ = clientWithRoute pm (Proxy :: Proxy api) - hoistClientMonad pm _ f cl = hoistClientMonad pm (Proxy :: Proxy api) f cl + hoistClientMonad pm _ = hoistClientMonad pm (Proxy :: Proxy api) -- | Ignore @'Description'@ in client functions. instance HasClient m api => HasClient m (Description desc :> api) where @@ -732,7 +729,7 @@ instance HasClient m api => HasClient m (Description desc :> api) where clientWithRoute pm _ = clientWithRoute pm (Proxy :: Proxy api) - hoistClientMonad pm _ f cl = hoistClientMonad pm (Proxy :: Proxy api) f cl + hoistClientMonad pm _ = hoistClientMonad pm (Proxy :: Proxy api) -- | If you use a 'QueryParam' in one of your endpoints in your API, -- the corresponding querying function will automatically take @@ -782,8 +779,7 @@ instance pname :: Text pname = pack $ symbolVal (Proxy :: Proxy sym) - hoistClientMonad pm _ f cl = \arg -> - hoistClientMonad pm (Proxy :: Proxy api) f (cl arg) + hoistClientMonad pm _ f cl = hoistClientMonad pm (Proxy :: Proxy api) f . cl -- | If you use a 'QueryParams' in one of your endpoints in your API, -- the corresponding querying function will automatically take @@ -833,8 +829,7 @@ instance pname = pack $ symbolVal (Proxy :: Proxy sym) paramlist' = map (Just . encodeQueryParamValue) paramlist - hoistClientMonad pm _ f cl = \as -> - hoistClientMonad pm (Proxy :: Proxy api) f (cl as) + hoistClientMonad pm _ f cl = hoistClientMonad pm (Proxy :: Proxy api) f . cl -- | If you use a 'QueryFlag' in one of your endpoints in your API, -- the corresponding querying function will automatically take @@ -876,8 +871,7 @@ instance where paramname = pack $ symbolVal (Proxy :: Proxy sym) - hoistClientMonad pm _ f cl = \b -> - hoistClientMonad pm (Proxy :: Proxy api) f (cl b) + hoistClientMonad pm _ f cl = hoistClientMonad pm (Proxy :: Proxy api) f . cl instance HasClient m api @@ -893,8 +887,7 @@ instance (Proxy :: Proxy api) (setQueryString query req) - hoistClientMonad pm _ f cl = \b -> - hoistClientMonad pm (Proxy :: Proxy api) f (cl b) + hoistClientMonad pm _ f cl = hoistClientMonad pm (Proxy :: Proxy api) f . cl instance (HasClient m api, KnownSymbol sym, ToDeepQuery a) @@ -916,8 +909,7 @@ instance (Proxy :: Proxy api) withParams - hoistClientMonad pm _ f cl = \b -> - hoistClientMonad pm (Proxy :: Proxy api) f (cl b) + hoistClientMonad pm _ f cl = hoistClientMonad pm (Proxy :: Proxy api) f . cl -- | Pick a 'Method' and specify where the server you want to query is. You get -- back the full `Response`. @@ -930,7 +922,7 @@ instance RunClient m => HasClient m Raw where clientWithRoute _pm Proxy req httpMethod = do runRequest req{requestMethod = httpMethod} - hoistClientMonad _ _ f cl = \meth -> f (cl meth) + hoistClientMonad _ _ f cl = f . cl instance RunClient m => HasClient m RawM where type @@ -941,7 +933,7 @@ instance RunClient m => HasClient m RawM where clientWithRoute _pm Proxy req httpMethod = do runRequest req{requestMethod = httpMethod} - hoistClientMonad _ _ f cl = \meth -> f (cl meth) + hoistClientMonad _ _ f cl = f . cl -- | If you use a 'ReqBody' in one of your endpoints in your API, -- the corresponding querying function will automatically take @@ -981,8 +973,7 @@ instance req ) - hoistClientMonad pm _ f cl = \a -> - hoistClientMonad pm (Proxy :: Proxy api) f (cl a) + hoistClientMonad pm _ f cl = hoistClientMonad pm (Proxy :: Proxy api) f . cl instance ( FramingRender framing @@ -994,8 +985,7 @@ instance where type Client m (StreamBody' mods framing ctype a :> api) = a -> Client m api - hoistClientMonad pm _ f cl = \a -> - hoistClientMonad pm (Proxy :: Proxy api) f (cl a) + hoistClientMonad pm _ f cl = hoistClientMonad pm (Proxy :: Proxy api) f . cl clientWithRoute pm Proxy req body = clientWithRoute pm (Proxy :: Proxy api) $ @@ -1022,31 +1012,25 @@ instance (HasClient m api, KnownSymbol path) => HasClient m (path :> api) where where p = toEncodedUrlPiece $ pack $ symbolVal (Proxy :: Proxy path) - hoistClientMonad pm _ f cl = hoistClientMonad pm (Proxy :: Proxy api) f cl + hoistClientMonad pm _ = hoistClientMonad pm (Proxy :: Proxy api) instance HasClient m api => HasClient m (Vault :> api) where type Client m (Vault :> api) = Client m api - clientWithRoute pm Proxy req = - clientWithRoute pm (Proxy :: Proxy api) req - - hoistClientMonad pm _ f cl = hoistClientMonad pm (Proxy :: Proxy api) f cl + clientWithRoute pm Proxy = clientWithRoute pm (Proxy :: Proxy api) + hoistClientMonad pm _ = hoistClientMonad pm (Proxy :: Proxy api) instance HasClient m api => HasClient m (RemoteHost :> api) where type Client m (RemoteHost :> api) = Client m api - clientWithRoute pm Proxy req = - clientWithRoute pm (Proxy :: Proxy api) req - - hoistClientMonad pm _ f cl = hoistClientMonad pm (Proxy :: Proxy api) f cl + clientWithRoute pm Proxy = clientWithRoute pm (Proxy :: Proxy api) + hoistClientMonad pm _ = hoistClientMonad pm (Proxy :: Proxy api) instance HasClient m api => HasClient m (IsSecure :> api) where type Client m (IsSecure :> api) = Client m api - clientWithRoute pm Proxy req = - clientWithRoute pm (Proxy :: Proxy api) req - - hoistClientMonad pm _ f cl = hoistClientMonad pm (Proxy :: Proxy api) f cl + clientWithRoute pm Proxy = clientWithRoute pm (Proxy :: Proxy api) + hoistClientMonad pm _ = hoistClientMonad pm (Proxy :: Proxy api) instance HasClient m subapi @@ -1055,7 +1039,7 @@ instance type Client m (WithNamedContext name context subapi) = Client m subapi clientWithRoute pm Proxy = clientWithRoute pm (Proxy :: Proxy subapi) - hoistClientMonad pm _ f cl = hoistClientMonad pm (Proxy :: Proxy subapi) f cl + hoistClientMonad pm _ = hoistClientMonad pm (Proxy :: Proxy subapi) instance HasClient m subapi @@ -1064,7 +1048,7 @@ instance type Client m (WithResource res :> subapi) = Client m subapi clientWithRoute pm Proxy = clientWithRoute pm (Proxy :: Proxy subapi) - hoistClientMonad pm _ f cl = hoistClientMonad pm (Proxy :: Proxy subapi) f cl + hoistClientMonad pm _ = hoistClientMonad pm (Proxy :: Proxy subapi) instance HasClient m api @@ -1077,8 +1061,7 @@ instance clientWithRoute pm Proxy req (AuthenticatedRequest (val, func)) = clientWithRoute pm (Proxy :: Proxy api) (func val req) - hoistClientMonad pm _ f cl = \authreq -> - hoistClientMonad pm (Proxy :: Proxy api) f (cl authreq) + hoistClientMonad pm _ f cl = hoistClientMonad pm (Proxy :: Proxy api) f . cl -- | Ignore @'Fragment'@ in client functions. -- See for more details. @@ -1115,8 +1098,7 @@ instance HasClient m api => HasClient m (BasicAuth realm usr :> api) where clientWithRoute pm Proxy req val = clientWithRoute pm (Proxy :: Proxy api) (basicAuthReq val req) - hoistClientMonad pm _ f cl = \bauth -> - hoistClientMonad pm (Proxy :: Proxy api) f (cl bauth) + hoistClientMonad pm _ f cl = hoistClientMonad pm (Proxy :: Proxy api) f . cl -- | A type that specifies that an API record contains a client implementation. data AsClientT (m :: Type -> Type) @@ -1305,10 +1287,10 @@ for empty and one for non-empty lists). checkContentTypeHeader :: RunClient m => Response -> m MediaType checkContentTypeHeader response = case lookup "Content-Type" $ toList $ responseHeaders response of - Nothing -> return $ "application" Media.// "octet-stream" + Nothing -> pure $ "application" Media.// "octet-stream" Just t -> case parseAccept t of Nothing -> throwClientError $ InvalidContentTypeHeader response - Just t' -> return t' + Just t' -> pure t' decodedAs :: forall ct a m @@ -1323,7 +1305,7 @@ decodedAs response@Response{responseBody = body} ct = do UnsupportedContentType responseContentType response case mimeUnrender ct body of Left err -> throwClientError $ DecodeFailure (T.pack err) response - Right val -> return val + Right val -> pure val where accept = toList $ contentTypes ct diff --git a/servant-client-core/src/Servant/Client/Core/Request.hs b/servant-client-core/src/Servant/Client/Core/Request.hs index 341aa9806..c1148a65e 100644 --- a/servant-client-core/src/Servant/Client/Core/Request.hs +++ b/servant-client-core/src/Servant/Client/Core/Request.hs @@ -1,6 +1,4 @@ {-# LANGUAGE DeriveDataTypeable #-} -{-# LANGUAGE DeriveFoldable #-} -{-# LANGUAGE DeriveFunctor #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE DeriveTraversable #-} {-# LANGUAGE MultiParamTypeClasses #-} @@ -76,19 +74,19 @@ instance showParen (p >= 11) ( showString "Request {requestPath = " - . showsPrec 0 (requestPath req) + . shows (requestPath req) . showString ", requestQueryString = " - . showsPrec 0 (requestQueryString req) + . shows (requestQueryString req) . showString ", requestBody = " - . showsPrec 0 (requestBody req) + . shows (requestBody req) . showString ", requestAccept = " - . showsPrec 0 (requestAccept req) + . shows (requestAccept req) . showString ", requestHeaders = " - . showsPrec 0 (redactSensitiveHeader <$> requestHeaders req) + . shows (redactSensitiveHeader <$> requestHeaders req) . showString ", requestHttpVersion = " - . showsPrec 0 (requestHttpVersion req) + . shows (requestHttpVersion req) . showString ", requestMethod = " - . showsPrec 0 (requestMethod req) + . shows (requestMethod req) . showString "}" ) where diff --git a/servant-client-core/src/Servant/Client/Core/RunClient.hs b/servant-client-core/src/Servant/Client/Core/RunClient.hs index d64a2e25c..0dbd3ce64 100644 --- a/servant-client-core/src/Servant/Client/Core/RunClient.hs +++ b/servant-client-core/src/Servant/Client/Core/RunClient.hs @@ -1,7 +1,6 @@ {-# LANGUAGE DeriveFunctor #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE MultiParamTypeClasses #-} -{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeOperators #-} diff --git a/servant-client-core/src/Servant/Client/Generic.hs b/servant-client-core/src/Servant/Client/Generic.hs index 01a8cb2dc..dc44a63d3 100644 --- a/servant-client-core/src/Servant/Client/Generic.hs +++ b/servant-client-core/src/Servant/Client/Generic.hs @@ -1,5 +1,4 @@ {-# LANGUAGE FlexibleContexts #-} -{-# LANGUAGE KindSignatures #-} {-# LANGUAGE RankNTypes #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeFamilies #-} diff --git a/servant-client-core/test/Servant/Client/Core/Internal/BaseUrlSpec.hs b/servant-client-core/test/Servant/Client/Core/Internal/BaseUrlSpec.hs index e625a7e91..f1564ac5f 100644 --- a/servant-client-core/test/Servant/Client/Core/Internal/BaseUrlSpec.hs +++ b/servant-client-core/test/Servant/Client/Core/Internal/BaseUrlSpec.hs @@ -74,11 +74,11 @@ instance Arbitrary BaseUrl where first <- elements letters middle <- listOf1 $ elements (letters ++ ['0' .. '9'] ++ ['.', '-']) last' <- elements letters - return (first : middle ++ [last']) + pure (first : middle ++ [last']) portGen = - frequency $ - (1, return 80) - : (1, return 443) - : (1, choose (1, 20000)) - : [] + frequency + [ (1, pure 80) + , (1, pure 443) + , (1, choose (1, 20000)) + ] pathGen = listOf1 . elements $ letters diff --git a/servant-client-ghcjs/src/Servant/Client/Internal/XhrClient.hs b/servant-client-ghcjs/src/Servant/Client/Internal/XhrClient.hs index 4bacd22ca..e0df54661 100644 --- a/servant-client-ghcjs/src/Servant/Client/Internal/XhrClient.hs +++ b/servant-client-ghcjs/src/Servant/Client/Internal/XhrClient.hs @@ -3,6 +3,7 @@ {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} +{-# LANGUAGE LambdaCase #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE ScopedTypeVariables #-} @@ -212,13 +213,13 @@ performXhr xhr burl request = do -- state 4 is fired will cause an MVar to be put. Subsequent -- fires are ignored. 4 -> void $ tryPutMVar waiter () - _ -> return () + _ -> pure () onReadyStateChange :: JSXMLHttpRequest -> IO () -> IO (Callback (IO ())) onReadyStateChange xhr action = do callback <- asyncCallback action js_onReadyStateChange xhr callback - return callback + pure callback foreign import javascript safe "$1.onreadystatechange = $2;" js_onReadyStateChange :: JSXMLHttpRequest -> Callback (IO ()) -> IO () @@ -279,17 +280,17 @@ foreign import javascript unsafe "$1.send($2)" toBody :: Request -> IO (Maybe ArrayBuffer) toBody request = case requestBody request of - Nothing -> return Nothing + Nothing -> pure Nothing Just (a, _) -> Just <$> go a where go :: RequestBody -> IO ArrayBuffer go x = case x of - RequestBodyLBS x -> return $ mBody $ BL.toStrict x - RequestBodyBS x -> return $ mBody x + RequestBodyLBS x -> pure $ mBody $ BL.toStrict x + RequestBodyBS x -> pure $ mBody x RequestBodySource xs -> - runExceptT (S.runSourceT xs) >>= \e -> case e of + runExceptT (S.runSourceT xs) >>= \case Left err -> fail err - Right bss -> return $ mBody $ BL.toStrict $ mconcat bss + Right bss -> pure $ mBody $ BL.toStrict $ mconcat bss mBody :: BS.ByteString -> ArrayBuffer mBody bs = js_bufferSlice offset len $ Buffer.getArrayBuffer buffer @@ -348,7 +349,7 @@ foreign import javascript unsafe "$1.response" parseHeaders :: String -> ResponseHeaders parseHeaders s = - first mk . first strip . second strip . parseHeader + first mk . bimap strip . parseHeader <$> splitOn "\r\n" (cs s) where parseHeader :: BS.ByteString -> (BS.ByteString, BS.ByteString) diff --git a/servant-client/src/Servant/Client/Internal/HttpClient.hs b/servant-client/src/Servant/Client/Internal/HttpClient.hs index f61ce9b4c..9f89cb23b 100644 --- a/servant-client/src/Servant/Client/Internal/HttpClient.hs +++ b/servant-client/src/Servant/Client/Internal/HttpClient.hs @@ -137,7 +137,7 @@ instance MonadBaseControl IO ClientM where -- | Try clients in order, last error is preserved. instance Alt ClientM where - a b = a `catchError` \_ -> b + a b = a `catchError` const b instance RunClient ClientM where runRequestAcceptStatus statuses req = do @@ -175,17 +175,17 @@ performRequest acceptStatus req = do Just good -> status `elem` good unless goodStatus $ do throwError $ mkFailureResponse burl req ourResponse - return ourResponse + pure ourResponse where requestWithoutCookieJar :: Client.Manager -> Client.Request -> ClientM (Client.Response BSL.ByteString) requestWithoutCookieJar m' request' = do eResponse <- liftIO . catchConnectionError $ Client.httpLbs request' m' - either throwError return eResponse + either throwError pure eResponse requestWithCookieJar :: Client.Manager -> Client.Request -> TVar Client.CookieJar -> ClientM (Client.Response BSL.ByteString) requestWithCookieJar m' request' cj = do eResponse <- liftIO . catchConnectionError . Client.withResponseHistory request' m' $ updateWithResponseCookies cj - either throwError return eResponse + either throwError pure eResponse updateWithResponseCookies :: TVar Client.CookieJar -> Client.HistoriedResponse Client.BodyReader -> IO (Client.Response BSL.ByteString) updateWithResponseCookies cj responses = do @@ -194,7 +194,7 @@ performRequest acceptStatus req = do let fRes' = fRes{Client.responseBody = BSL.fromChunks bss} allResponses = Client.hrRedirects responses <> [(fReq, fRes')] atomically $ mapM_ (updateCookieJar now) allResponses - return fRes' + pure fRes' where updateCookieJar :: UTCTime -> (Client.Request, Client.Response BSL.ByteString) -> STM () updateCookieJar now' (req', res') = modifyTVar' cj (fst . Client.updateCookieJar res' req' now') @@ -272,7 +272,7 @@ defaultMakeClientRequest burl r = needsPopper popper - nextBs S.Stop = return (S.Stop, BS.empty) + nextBs S.Stop = pure (S.Stop, BS.empty) nextBs (S.Error err) = fail err nextBs (S.Skip s) = nextBs s nextBs (S.Effect ms) = ms >>= nextBs @@ -280,7 +280,7 @@ defaultMakeClientRequest burl r = [] -> nextBs s (x : xs) | BS.null x -> nextBs step' - | otherwise -> return (step', x) + | otherwise -> pure (step', x) where step' = S.Yield (BSL.fromChunks xs) s diff --git a/servant-client/src/Servant/Client/Internal/HttpClient/Streaming.hs b/servant-client/src/Servant/Client/Internal/HttpClient/Streaming.hs index 0eedf9401..55031534b 100644 --- a/servant-client/src/Servant/Client/Internal/HttpClient/Streaming.hs +++ b/servant-client/src/Servant/Client/Internal/HttpClient/Streaming.hs @@ -109,7 +109,7 @@ instance MonadBase IO ClientM where -- | Try clients in order, last error is preserved. instance Alt ClientM where - a b = a `catchError` \_ -> b + a b = a `catchError` const b instance RunClient ClientM where runRequestAcceptStatus = performRequest @@ -168,7 +168,7 @@ performRequest acceptStatus req = do Just good -> status `elem` good unless goodStatus $ do throwError $ mkFailureResponse burl req ourResponse - return ourResponse + pure ourResponse -- | TODO: support UVerb ('acceptStatus' argument, like in 'performRequest' above). performWithStreamingRequest :: Request -> (StreamingResponse -> IO a) -> ClientM a diff --git a/servant-client/test/Servant/BasicAuthSpec.hs b/servant-client/test/Servant/BasicAuthSpec.hs index b9e6d4348..c26efdc0f 100644 --- a/servant-client/test/Servant/BasicAuthSpec.hs +++ b/servant-client/test/Servant/BasicAuthSpec.hs @@ -9,7 +9,6 @@ {-# LANGUAGE PolyKinds #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeFamilies #-} -{-# LANGUAGE TypeOperators #-} {-# LANGUAGE UndecidableInstances #-} {-# OPTIONS_GHC -fno-warn-name-shadowing #-} {-# OPTIONS_GHC -fno-warn-orphans #-} diff --git a/servant-client/test/Servant/BrokenSpec.hs b/servant-client/test/Servant/BrokenSpec.hs index e4100faa1..11f629235 100644 --- a/servant-client/test/Servant/BrokenSpec.hs +++ b/servant-client/test/Servant/BrokenSpec.hs @@ -59,11 +59,11 @@ brokenSpec = beforeAll (startWaiApp brokenServer) $ afterAll endWaiApp $ do it "reports FailureResponse with wrong 2xx status code" $ \(_, baseUrl) -> do res <- runClient get200Client baseUrl case res of - Left (FailureResponse _ r) | responseStatusCode r == HTTP.status201 -> return () + Left (FailureResponse _ r) | responseStatusCode r == HTTP.status201 -> pure () _ -> fail $ "expected 201 broken response, but got " <> show res it "reports FailureResponse with wrong 3xx status code" $ \(_, baseUrl) -> do res <- runClient get307Client baseUrl case res of - Left (FailureResponse _ r) | responseStatusCode r == HTTP.status301 -> return () + Left (FailureResponse _ r) | responseStatusCode r == HTTP.status301 -> pure () _ -> fail $ "expected 301 broken response, but got " <> show res diff --git a/servant-client/test/Servant/ClientTestUtils.hs b/servant-client/test/Servant/ClientTestUtils.hs index 76933324b..2af8bbc9e 100644 --- a/servant-client/test/Servant/ClientTestUtils.hs +++ b/servant-client/test/Servant/ClientTestUtils.hs @@ -164,7 +164,7 @@ instance FromDeepQuery Filter where let maybeToRight l = maybe (Left l) Right age' <- maybeToRight "missing age" $ readMaybe . Text.unpack =<< join (lookup ["age"] params) name' <- maybeToRight "missing name" $ join $ lookup ["name"] params - return $ Filter age' (Text.unpack name') + pure $ Filter age' (Text.unpack name') instance ToDeepQuery Filter where toDeepQuery (Filter age' name') = @@ -335,15 +335,15 @@ server :: Application server = serve api - ( return carol - :<|> return alice - :<|> return "redirecting" - :<|> return NoContent - :<|> (\name -> return $ Person name 0) - :<|> (\names -> return (zipWith Person names [0 ..])) - :<|> return + ( pure carol + :<|> pure alice + :<|> pure "redirecting" + :<|> pure NoContent + :<|> (\name -> pure $ Person name 0) + :<|> (\names -> pure (zipWith Person names [0 ..])) + :<|> pure :<|> ( \case - Just "alice" -> return alice + Just "alice" -> pure alice Just n -> throwError $ ServerError 400 (n ++ " not found") "" [] Nothing -> throwError $ ServerError 400 "missing parameter" "" [] ) @@ -357,31 +357,31 @@ server = . lookup "payload" $ Wai.queryString request ) - :<|> (\names -> return (zipWith Person names [0 ..])) - :<|> return + :<|> (\names -> pure (zipWith Person names [0 ..])) + :<|> pure :<|> ( \q -> - return + pure alice { _name = maybe mempty C8.unpack $ join (lookup "name" q) , _age = fromMaybe 0 (readMaybe . C8.unpack =<< join (lookup "age" q)) } ) :<|> ( \filter' -> - return + pure alice { _name = nameFilter filter' , _age = ageFilter filter' } ) - :<|> return alice + :<|> pure alice :<|> Tagged (\_request respond -> respond $ Wai.responseLBS HTTP.ok200 [] "rawSuccess") :<|> Tagged (\request respond -> respond $ Wai.responseLBS HTTP.ok200 (Wai.requestHeaders request) "rawSuccess") :<|> Tagged (\_request respond -> respond $ Wai.responseLBS HTTP.badRequest400 [] "rawFailure") - :<|> (\a b c d -> return (a, b, c, d)) - :<|> return (addHeader 1729 $ addHeader "eg2" True) + :<|> (\a b c d -> pure (a, b, c, d)) + :<|> pure (addHeader 1729 $ addHeader "eg2" True) :<|> (pure . Z . I . WithStatus $ addHeader 1729 $ addHeader "eg2" True) - :<|> return (addHeader "cookie1" $ addHeader "cookie2" True) - :<|> return NoContent + :<|> pure (addHeader "cookie1" $ addHeader "cookie2" True) + :<|> pure NoContent :<|> Tagged (\_request respond -> respond $ Wai.responseLBS HTTP.found302 [("Location", "testlocation"), ("Set-Cookie", "testcookie=test")] "") :<|> emptyServer :<|> ( \shouldRedirect -> @@ -445,15 +445,15 @@ basicAuthHandler :: BasicAuthCheck () basicAuthHandler = let check (BasicAuthData username password) = if username == "servant" && password == "server" - then return (Authorized ()) - else return Unauthorized + then pure (Authorized ()) + else pure Unauthorized in BasicAuthCheck check basicServerContext :: Context '[BasicAuthCheck ()] basicServerContext = basicAuthHandler :. EmptyContext basicAuthServer :: Application -basicAuthServer = serveWithContext basicAuthAPI basicServerContext (const (return alice)) +basicAuthServer = serveWithContext basicAuthAPI basicServerContext (const (pure alice)) -- * general auth stuff @@ -471,14 +471,14 @@ genAuthHandler :: AuthHandler Wai.Request () genAuthHandler = let handler req = case lookup "AuthHeader" (Wai.requestHeaders req) of Nothing -> throwError (err401{errBody = "Missing auth header"}) - Just _ -> return () + Just _ -> pure () in mkAuthHandler handler genAuthServerContext :: Context '[AuthHandler Wai.Request ()] genAuthServerContext = genAuthHandler :. EmptyContext genAuthServer :: Application -genAuthServer = serveWithContext genAuthAPI genAuthServerContext (const (return alice)) +genAuthServer = serveWithContext genAuthAPI genAuthServerContext (const (pure alice)) {-# NOINLINE manager' #-} manager' :: C.Manager @@ -494,7 +494,7 @@ startWaiApp app = do (port, socket) <- openTestSocket let settings = setPort port defaultSettings thread <- forkIO $ runSettingsSocket settings socket app - return (thread, BaseUrl Http "localhost" port "") + pure (thread, BaseUrl Http "localhost" port "") endWaiApp :: (ThreadId, BaseUrl) -> IO () endWaiApp (thread, _) = killThread thread @@ -506,7 +506,7 @@ openTestSocket = do bind s (SockAddrInet defaultPort localhost) listen s 1 port <- socketPort s - return (fromIntegral port, s) + pure (fromIntegral port, s) pathGen :: Gen (NonEmptyList Char) pathGen = fmap NonEmpty path @@ -545,4 +545,4 @@ usersServer :: Maybe (Range 1 100) -> Handler [Person] usersServer mpage = do let pageNum = maybe 1 unRange mpage -- pageNum is guaranteed to be between 1 and 100 - return [Person "Example" $ fromIntegral pageNum] + pure [Person "Example" $ fromIntegral pageNum] diff --git a/servant-client/test/Servant/ConnectionErrorSpec.hs b/servant-client/test/Servant/ConnectionErrorSpec.hs index eaabba5a0..13ffa6ef2 100644 --- a/servant-client/test/Servant/ConnectionErrorSpec.hs +++ b/servant-client/test/Servant/ConnectionErrorSpec.hs @@ -10,7 +10,6 @@ {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeApplications #-} {-# LANGUAGE TypeFamilies #-} -{-# LANGUAGE TypeOperators #-} {-# LANGUAGE UndecidableInstances #-} {-# OPTIONS_GHC -fno-warn-name-shadowing #-} {-# OPTIONS_GHC -fno-warn-orphans #-} diff --git a/servant-client/test/Servant/FailSpec.hs b/servant-client/test/Servant/FailSpec.hs index b774d1a41..235595af2 100644 --- a/servant-client/test/Servant/FailSpec.hs +++ b/servant-client/test/Servant/FailSpec.hs @@ -9,7 +9,6 @@ {-# LANGUAGE PolyKinds #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeFamilies #-} -{-# LANGUAGE TypeOperators #-} {-# LANGUAGE UndecidableInstances #-} {-# OPTIONS_GHC -fno-warn-name-shadowing #-} {-# OPTIONS_GHC -fno-warn-orphans #-} @@ -38,39 +37,39 @@ failSpec = beforeAll (startWaiApp failServer) $ afterAll endWaiApp $ do let (_ :<|> _ :<|> _ :<|> getDeleteEmpty :<|> _) = client api Left res <- runClient getDeleteEmpty baseUrl case res of - FailureResponse _ r | responseStatusCode r == HTTP.status404 -> return () + FailureResponse _ r | responseStatusCode r == HTTP.status404 -> pure () _ -> fail $ "expected 404 response, but got " <> show res it "reports DecodeFailure" $ \(_, baseUrl) -> do let (_ :<|> _ :<|> _ :<|> _ :<|> getCapture :<|> _) = client api Left res <- runClient (getCapture "foo") baseUrl case res of - DecodeFailure _ _ -> return () + DecodeFailure _ _ -> pure () _ -> fail $ "expected DecodeFailure, but got " <> show res it "reports ConnectionError" $ \_ -> do let (getGetWrongHost :<|> _) = client api Left res <- runClient getGetWrongHost (BaseUrl Http "127.0.0.1" 19872 "") case res of - ConnectionError _ -> return () + ConnectionError _ -> pure () _ -> fail $ "expected ConnectionError, but got " <> show res it "reports UnsupportedContentType" $ \(_, baseUrl) -> do let (_ :<|> getGet :<|> _) = client api Left res <- runClient getGet baseUrl case res of - UnsupportedContentType "application/octet-stream" _ -> return () + UnsupportedContentType "application/octet-stream" _ -> pure () _ -> fail $ "expected UnsupportedContentType, but got " <> show res it "reports UnsupportedContentType when there are response headers" $ \(_, baseUrl) -> do Left res <- runClient getRespHeaders baseUrl case res of - UnsupportedContentType "application/x-www-form-urlencoded" _ -> return () + UnsupportedContentType "application/x-www-form-urlencoded" _ -> pure () _ -> fail $ "expected UnsupportedContentType, but got " <> show res it "reports InvalidContentTypeHeader" $ \(_, baseUrl) -> do let (_ :<|> _ :<|> _ :<|> _ :<|> _ :<|> _ :<|> getBody :<|> _) = client api Left res <- runClient (getBody alice) baseUrl case res of - InvalidContentTypeHeader _ -> return () + InvalidContentTypeHeader _ -> pure () _ -> fail $ "expected InvalidContentTypeHeader, but got " <> show res diff --git a/servant-client/test/Servant/GenAuthSpec.hs b/servant-client/test/Servant/GenAuthSpec.hs index ea73172e5..03c58e57d 100644 --- a/servant-client/test/Servant/GenAuthSpec.hs +++ b/servant-client/test/Servant/GenAuthSpec.hs @@ -9,7 +9,6 @@ {-# LANGUAGE PolyKinds #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeFamilies #-} -{-# LANGUAGE TypeOperators #-} {-# LANGUAGE UndecidableInstances #-} {-# OPTIONS_GHC -fno-warn-name-shadowing #-} {-# OPTIONS_GHC -fno-warn-orphans #-} diff --git a/servant-client/test/Servant/GenericSpec.hs b/servant-client/test/Servant/GenericSpec.hs index a68668441..1cfbe9308 100644 --- a/servant-client/test/Servant/GenericSpec.hs +++ b/servant-client/test/Servant/GenericSpec.hs @@ -9,7 +9,6 @@ {-# LANGUAGE PolyKinds #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeFamilies #-} -{-# LANGUAGE TypeOperators #-} {-# LANGUAGE UndecidableInstances #-} {-# OPTIONS_GHC -fno-warn-name-shadowing #-} {-# OPTIONS_GHC -fno-warn-orphans #-} diff --git a/servant-client/test/Servant/HoistClientSpec.hs b/servant-client/test/Servant/HoistClientSpec.hs index 8aca02890..5e38f1f47 100644 --- a/servant-client/test/Servant/HoistClientSpec.hs +++ b/servant-client/test/Servant/HoistClientSpec.hs @@ -7,7 +7,6 @@ {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE PolyKinds #-} -{-# LANGUAGE RecordWildCards #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeOperators #-} @@ -39,7 +38,7 @@ hoistClientAPI :: Proxy HoistClientAPI hoistClientAPI = Proxy hoistClientServer :: Application -- implements HoistClientAPI -hoistClientServer = serve hoistClientAPI $ return 5 :<|> return +hoistClientServer = serve hoistClientAPI $ pure 5 :<|> pure hoistClientSpec :: Spec hoistClientSpec = beforeAll (startWaiApp hoistClientServer) $ afterAll endWaiApp $ do diff --git a/servant-client/test/Servant/StreamSpec.hs b/servant-client/test/Servant/StreamSpec.hs index 03f26aae5..e5a9a78ff 100644 --- a/servant-client/test/Servant/StreamSpec.hs +++ b/servant-client/test/Servant/StreamSpec.hs @@ -77,11 +77,11 @@ bob = Person "Bob" 25 server :: Application server = serve api $ - return (source [alice, bob, alice]) - :<|> return (source [alice, bob, alice]) + pure (source [alice, bob, alice]) + :<|> pure (source [alice, bob, alice]) -- 2 ^ (18 + 10) = 256M - :<|> return (SourceT ($ lots (powerOfTwo 18))) - :<|> return + :<|> pure (SourceT ($ lots (powerOfTwo 18))) + :<|> pure where lots n | n < 0 = Stop @@ -89,7 +89,7 @@ server = let size = powerOfTwo 10 mbs <- getHardwareEntropy size bs <- maybe (getEntropy size) pure mbs - return (Yield bs (lots (n - 1))) + pure (Yield bs (lots (n - 1))) powerOfTwo :: Int -> Int powerOfTwo = (2 ^) diff --git a/servant-client/test/Servant/SuccessSpec.hs b/servant-client/test/Servant/SuccessSpec.hs index 6eabc9630..435f97a05 100644 --- a/servant-client/test/Servant/SuccessSpec.hs +++ b/servant-client/test/Servant/SuccessSpec.hs @@ -49,7 +49,7 @@ import Servant.ClientTestUtils _ = client comprehensiveAPIWithoutStreaming spec :: Spec -spec = describe "Servant.SuccessSpec" $ successSpec +spec = describe "Servant.SuccessSpec" successSpec successSpec :: Spec successSpec = beforeAll (startWaiApp server) $ afterAll endWaiApp $ do @@ -100,7 +100,12 @@ successSpec = beforeAll (startWaiApp server) $ afterAll endWaiApp $ do let qs = [("name", Just "bob"), ("age", Just "1")] left show <$> runClient (getQueryString qs) baseUrl `shouldReturn` Right (Person "bob" 1) - it "Servant.API.QueryParam.DeepQuery" $ \(_, baseUrl) -> left show <$> runClient (getDeepQuery $ Filter 1 "bob") baseUrl `shouldReturn` (Right (Person "bob" 1)) + it "Servant.API.QueryParam.DeepQuery" $ \(_, baseUrl) -> + left show + <$> runClient + (getDeepQuery $ Filter 1 "bob") + baseUrl + `shouldReturn` Right (Person "bob" 1) it "Servant.API.Fragment" $ \(_, baseUrl) -> left id <$> runClient getFragment baseUrl `shouldReturn` Right alice @@ -164,13 +169,13 @@ successSpec = beforeAll (startWaiApp server) $ afterAll endWaiApp $ do Left e -> assertFailure $ show e Right r -> - ("X-Added-Header", "XXX") `elem` toList (responseHeaders r) `shouldBe` True + (("X-Added-Header", "XXX") `elem` responseHeaders r) `shouldBe` True modifyMaxSuccess (const 20) $ it "works for a combination of Capture, QueryParam, QueryFlag and ReqBody" $ \(_, baseUrl) -> property $ forAllShrink pathGen shrink $ \(NonEmpty cap) num flag body -> ioProperty $ do result <- left show <$> runClient (getMultiple cap num flag body) baseUrl - return $ + pure $ result === Right (cap, num, flag, body) context "With a route that can either return success or redirect" $ do diff --git a/servant-client/test/Servant/WrappedApiSpec.hs b/servant-client/test/Servant/WrappedApiSpec.hs index 6a5d56304..66dd6ad25 100644 --- a/servant-client/test/Servant/WrappedApiSpec.hs +++ b/servant-client/test/Servant/WrappedApiSpec.hs @@ -57,9 +57,10 @@ wrappedApiSpec = describe "error status codes" $ do getResponse = client api Left (FailureResponse _ r) <- runClient getResponse baseUrl responseStatusCode r `shouldBe` HTTP.Status 500 "error message" - in mapM_ test $ - (WrappedApi (Proxy :: Proxy (Delete '[JSON] ())), "Delete") - : (WrappedApi (Proxy :: Proxy (Get '[JSON] ())), "Get") - : (WrappedApi (Proxy :: Proxy (Post '[JSON] ())), "Post") - : (WrappedApi (Proxy :: Proxy (Put '[JSON] ())), "Put") - : [] + in mapM_ + test + [ (WrappedApi (Proxy :: Proxy (Delete '[JSON] ())), "Delete") + , (WrappedApi (Proxy :: Proxy (Get '[JSON] ())), "Get") + , (WrappedApi (Proxy :: Proxy (Post '[JSON] ())), "Post") + , (WrappedApi (Proxy :: Proxy (Put '[JSON] ())), "Put") + ] diff --git a/servant-conduit/example/Main.hs b/servant-conduit/example/Main.hs index 8de4a8507..ba0820faf 100644 --- a/servant-conduit/example/Main.hs +++ b/servant-conduit/example/Main.hs @@ -1,5 +1,5 @@ {-# LANGUAGE DataKinds #-} -{-# LANGUAGE DeriveGeneric #-} +{-# LANGUAGE LambdaCase #-} {-# LANGUAGE TypeOperators #-} module Main (main) where @@ -43,19 +43,19 @@ server = fast :<|> slow :<|> readme :<|> proxy where fast n = liftIO $ do putStrLn $ "/get/" ++ show n - return $ fastConduit n + pure $ fastConduit n slow n = liftIO $ do putStrLn $ "/slow/" ++ show n - return $ slowConduit n + pure $ slowConduit n readme = liftIO $ do putStrLn "/readme" - return (C.sourceFile "README.md") + pure (C.sourceFile "README.md") proxy c = liftIO $ do putStrLn "/proxy" - return c + pure c -- for some reason unfold leaks? fastConduit = C.unfold mk @@ -84,7 +84,7 @@ main = do n <- maybe (fail $ "not a number: " ++ ns) pure $ readMaybe ns mgr <- newManager defaultManagerSettings burl <- parseBaseUrl "http://localhost:8000/" - withClientM (cli n) (mkClientEnv mgr burl) $ \me -> case me of + withClientM (cli n) (mkClientEnv mgr burl) $ \case Left err -> print err Right c -> do x <- connect c $ C.foldl (\p _ -> p + 1) (0 :: Int) diff --git a/servant-conduit/src/Servant/Conduit.hs b/servant-conduit/src/Servant/Conduit.hs index 8d0aaf793..1c2f92207 100644 --- a/servant-conduit/src/Servant/Conduit.hs +++ b/servant-conduit/src/Servant/Conduit.hs @@ -59,15 +59,15 @@ instance toSourceIO = conduitToSourceIO instance (MonadIO m, r ~ ()) => FromSourceIO o (ConduitT i o m r) where - fromSourceIO src = return $ + fromSourceIO src = pure $ ConduitT $ \con -> PipeM $ liftIO $ S.unSourceT src $ \step -> loop con step where loop :: MonadIO m => (() -> Pipe i i o () m b) -> S.StepT IO o -> IO (Pipe i i o () m b) - loop con S.Stop = return (con ()) + loop con S.Stop = pure (con ()) loop _con (S.Error err) = fail err loop con (S.Skip s) = loop con s loop con (S.Effect ms) = ms >>= loop con - loop con (S.Yield x s) = return (HaveOutput (PipeM (liftIO $ loop con s)) x) + loop con (S.Yield x s) = pure (HaveOutput (PipeM (liftIO $ loop con s)) x) {-# SPECIALIZE INLINE fromSourceIO :: SourceIO o -> IO (ConduitT i o IO ()) #-} diff --git a/servant-docs/src/Servant/Docs/Internal.hs b/servant-docs/src/Servant/Docs/Internal.hs index 3345f6a97..b8e35086b 100644 --- a/servant-docs/src/Servant/Docs/Internal.hs +++ b/servant-docs/src/Servant/Docs/Internal.hs @@ -5,7 +5,6 @@ {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE FunctionalDependencies #-} -{-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE PolyKinds #-} {-# LANGUAGE RecordWildCards #-} @@ -42,6 +41,7 @@ import qualified Data.ByteString.Char8 as BSC import Data.ByteString.Lazy.Char8 (ByteString) import qualified Data.CaseInsensitive as CI import Data.Foldable (fold, toList) +import Data.Functor import Data.HashMap.Strict (HashMap) import qualified Data.HashMap.Strict as HM import Data.Hashable (Hashable) @@ -240,7 +240,7 @@ instance Monoid (ExtraInfo a) where ExtraInfo $ HM.unionWith combineAction a b -- | Documentation options. -data DocOptions = DocOptions +newtype DocOptions = DocOptions { _maxSamples :: Int -- ^ Maximum samples allowed. } @@ -686,6 +686,9 @@ markdown = markdownWith defRenderingOptions -- @ -- -- @since 0.11.1 + +{- HLINT ignore markdownWith "Use list comprehension" -} +{- HLINT ignore markdownWith "Use list literal" -} markdownWith :: RenderingOptions -> API -> String markdownWith RenderingOptions{..} api = unlines $ @@ -705,7 +708,6 @@ markdownWith RenderingOptions{..} api = ++ rqbodyStr (action ^. rqtypes) (action ^. rqbody) ++ responseStr (action ^. response) ++ maybe [] (curlStr endpoint (action ^. headers) (action ^. rqbody)) _renderCurlBasePath - ++ [] where str = "## " @@ -723,8 +725,7 @@ markdownWith RenderingOptions{..} api = ("## " ++ i ^. introTitle) : "" : intersperse "" (i ^. introBody) - ++ "" - : [] + ++ [""] notesStr :: [DocNote] -> [String] notesStr = @@ -738,8 +739,7 @@ markdownWith RenderingOptions{..} api = (hdr ++ nt ^. noteTitle) : "" : intersperse "" (nt ^. noteBody) - ++ "" - : [] + ++ [""] where hdr | isJust _notesHeading = "#### " @@ -748,16 +748,16 @@ markdownWith RenderingOptions{..} api = authStr :: [DocAuthentication] -> [String] authStr [] = [] authStr auths = - let authIntros = mapped %~ view authIntro $ auths - clientInfos = mapped %~ view authDataRequired $ auths - in "### Authentication" - : "" - : unlines authIntros - : "" - : "Clients must supply the following data" - : unlines clientInfos - : "" - : [] + let authIntros = auths <&> view authIntro + clientInfos = auths <&> view authDataRequired + in [ "### Authentication" + , "" + , unlines authIntros + , "" + , "Clients must supply the following data" + , unlines clientInfos + , "" + ] capturesStr :: [DocCapture] -> [String] capturesStr [] = [] @@ -765,8 +765,7 @@ markdownWith RenderingOptions{..} api = "### Captures:" : "" : map captureStr l - ++ "" - : [] + ++ [""] captureStr cap = "- *" ++ (cap ^. capSymbol) ++ "*: " ++ (cap ^. capDesc) @@ -777,8 +776,7 @@ markdownWith RenderingOptions{..} api = "### Headers:" : "" : map headerStr l - ++ "" - : [] + ++ [""] where headerStr hname = "- This endpoint is sensitive to the value of the **" @@ -791,18 +789,17 @@ markdownWith RenderingOptions{..} api = ("### " ++ cs m ++ " Parameters:") : "" : map (paramStr m) l - ++ "" - : [] + ++ [""] paramStr m param = unlines $ ("- " ++ param ^. paramName) - : ( if (not (null values) || param ^. paramKind /= Flag) + : ( if not (null values) || (param ^. paramKind /= Flag) then [" - **Values**: *" ++ intercalate ", " values ++ "*"] else [] ) ++ (" - **Description**: " ++ param ^. paramDesc) - : ( if (param ^. paramKind == List) + : ( if param ^. paramKind == List then [ " - This parameter is a **list**. All " ++ cs m @@ -812,11 +809,10 @@ markdownWith RenderingOptions{..} api = ] else [] ) - ++ ( if (param ^. paramKind == Flag) + ++ ( if param ^. paramKind == Flag then [" - This parameter is a **flag**. This means no value is expected to be associated to this parameter."] else [] ) - ++ [] where values = param ^. paramValues @@ -879,12 +875,12 @@ markdownWith RenderingOptions{..} api = (_, _) -> "" contentStr mime_type body = - "" - : "```" <> markdownForType mime_type - : cs body - : "```" - : "" - : [] + [ "" + , "```" <> markdownForType mime_type + , cs body + , "```" + , "" + ] responseStr :: Response -> [String] responseStr resp = @@ -992,7 +988,7 @@ instance HasDocs (Capture' mods sym a :> api) => HasDocs (Capture' (mod ': mods) sym a :> api) where - docsFor Proxy = + docsFor _ = docsFor apiP where apiP = Proxy :: Proxy (Capture' mods sym a :> api) @@ -1207,8 +1203,7 @@ instance -- | TODO: this instance is incomplete. instance (Accept ctype, HasDocs api) => HasDocs (StreamBody' mods framing ctype a :> api) where - docsFor Proxy (endpoint, action) opts = - docsFor subApiP (endpoint, action') opts + docsFor Proxy (endpoint, action) = docsFor subApiP (endpoint, action') where subApiP = Proxy :: Proxy api @@ -1226,20 +1221,16 @@ instance (HasDocs api, KnownSymbol path) => HasDocs (path :> api) where pa = Proxy :: Proxy path instance HasDocs api => HasDocs (RemoteHost :> api) where - docsFor Proxy ep = - docsFor (Proxy :: Proxy api) ep + docsFor Proxy = docsFor (Proxy :: Proxy api) instance HasDocs api => HasDocs (IsSecure :> api) where - docsFor Proxy ep = - docsFor (Proxy :: Proxy api) ep + docsFor Proxy = docsFor (Proxy :: Proxy api) instance HasDocs api => HasDocs (HttpVersion :> api) where - docsFor Proxy ep = - docsFor (Proxy :: Proxy api) ep + docsFor Proxy = docsFor (Proxy :: Proxy api) instance HasDocs api => HasDocs (Vault :> api) where - docsFor Proxy ep = - docsFor (Proxy :: Proxy api) ep + docsFor Proxy = docsFor (Proxy :: Proxy api) instance HasDocs api => HasDocs (WithNamedContext name context api) where docsFor Proxy = docsFor (Proxy :: Proxy api) diff --git a/servant-docs/src/Servant/Docs/Internal/Pretty.hs b/servant-docs/src/Servant/Docs/Internal/Pretty.hs index 5ce67a43e..1c01c68b4 100644 --- a/servant-docs/src/Servant/Docs/Internal/Pretty.hs +++ b/servant-docs/src/Servant/Docs/Internal/Pretty.hs @@ -1,6 +1,5 @@ {-# LANGUAGE DataKinds #-} {-# LANGUAGE FlexibleInstances #-} -{-# LANGUAGE KindSignatures #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE PolyKinds #-} diff --git a/servant-docs/test/Servant/DocsSpec.hs b/servant-docs/test/Servant/DocsSpec.hs index 56cf0c55e..0a642b3a7 100644 --- a/servant-docs/test/Servant/DocsSpec.hs +++ b/servant-docs/test/Servant/DocsSpec.hs @@ -8,7 +8,6 @@ {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TypeOperators #-} -{-# LANGUAGE TypeSynonymInstances #-} {-# OPTIONS_GHC -fno-warn-orphans #-} {-# OPTIONS_GHC -freduction-depth=100 #-} @@ -96,15 +95,15 @@ spec = describe "Servant.Docs" $ do describe "tuple samples" $ do it "looks like expected" $ do - (toSample (Proxy :: Proxy (TT, UT))) `shouldBe` Just (TT1, UT1) - (toSample (Proxy :: Proxy (TT, UT, UT))) `shouldBe` Just (TT1, UT1, UT1) - (toSamples (Proxy :: Proxy (TT, UT))) + toSample (Proxy :: Proxy (TT, UT)) `shouldBe` Just (TT1, UT1) + toSample (Proxy :: Proxy (TT, UT, UT)) `shouldBe` Just (TT1, UT1, UT1) + toSamples (Proxy :: Proxy (TT, UT)) `shouldBe` [ ("eins, yks", (TT1, UT1)) , ("eins, kaks", (TT1, UT2)) , ("zwei, yks", (TT2, UT1)) , ("zwei, kaks", (TT2, UT2)) ] - (toSamples (Proxy :: Proxy (TT, UT, UT))) + toSamples (Proxy :: Proxy (TT, UT, UT)) `shouldBe` [ ("eins, yks, yks", (TT1, UT1, UT1)) , ("eins, yks, kaks", (TT1, UT1, UT2)) , ("zwei, yks, yks", (TT2, UT1, UT1)) @@ -216,7 +215,7 @@ shouldContain :: (Eq a, HasCallStack, Show a) => [a] -> [a] -> Assertion shouldContain = compareWith (flip isInfixOf) "does not contain" shouldNotContain :: (Eq a, HasCallStack, Show a) => [a] -> [a] -> Assertion -shouldNotContain = compareWith (\x y -> not (isInfixOf y x)) "contains" +shouldNotContain = compareWith (\x y -> not (y `isInfixOf` x)) "contains" compareWith :: (HasCallStack, Show a, Show b) => (a -> b -> Bool) -> String -> a -> b -> Assertion compareWith f msg x y = @@ -228,4 +227,4 @@ golden :: TestName -> FilePath -> String -> TestTreeM () golden n fp contents = TestTreeM $ tell - [goldenVsString n fp (return (cs contents))] + [goldenVsString n fp (pure (cs contents))] diff --git a/servant-foreign/src/Servant/Foreign/Internal.hs b/servant-foreign/src/Servant/Foreign/Internal.hs index 00b90218a..db491e3ee 100644 --- a/servant-foreign/src/Servant/Foreign/Internal.hs +++ b/servant-foreign/src/Servant/Foreign/Internal.hs @@ -15,7 +15,16 @@ module Servant.Foreign.Internal where -import Control.Lens (Getter, makeLenses, makePrisms, (%~), (&), (.~), (<>~)) +import Control.Lens + ( Getter + , makeLenses + , makePrisms + , (%~) + , (&) + , (.~) + , (<>~) + , (?~) + ) import Data.Data (Data) import Data.Kind (Type) import Data.Proxy @@ -339,7 +348,7 @@ instance req & reqFuncName . _FunctionName %~ (methodLC :) & reqMethod .~ method - & reqReturnType .~ Just retType + & reqReturnType ?~ retType where retType = typeFor lang (Proxy :: Proxy ftype) (Proxy :: Proxy a) method = reflectMethod (Proxy :: Proxy method) @@ -355,7 +364,7 @@ instance req & reqFuncName . _FunctionName %~ (methodLC :) & reqMethod .~ method - & reqReturnType .~ Just retType + & reqReturnType ?~ retType where retType = typeFor lang (Proxy :: Proxy ftype) (Proxy :: Proxy NoContent) method = reflectMethod (Proxy :: Proxy method) @@ -372,7 +381,7 @@ instance req & reqFuncName . _FunctionName %~ (methodLC :) & reqMethod .~ method - & reqReturnType .~ Just retType + & reqReturnType ?~ retType where retType = typeFor lang (Proxy :: Proxy ftype) (Proxy :: Proxy a) method = reflectMethod (Proxy :: Proxy method) @@ -452,7 +461,7 @@ instance type Foreign ftype (Fragment a :> api) = Foreign ftype api foreignFor lang Proxy Proxy req = foreignFor lang (Proxy :: Proxy ftype) (Proxy :: Proxy api) $ - req & reqUrl . frag .~ Just argT + req & reqUrl . frag ?~ argT where argT = typeFor lang (Proxy :: Proxy ftype) (Proxy :: Proxy (Maybe a)) @@ -472,7 +481,7 @@ instance foreignFor lang ftype Proxy req = foreignFor lang ftype (Proxy :: Proxy api) $ - req & reqBody .~ (Just $ typeFor lang ftype (Proxy :: Proxy a)) + req & reqBody ?~ typeFor lang ftype (Proxy :: Proxy a) instance HasForeign lang ftype api @@ -502,8 +511,7 @@ instance where type Foreign ftype (RemoteHost :> api) = Foreign ftype api - foreignFor lang ftype Proxy req = - foreignFor lang ftype (Proxy :: Proxy api) req + foreignFor lang ftype Proxy = foreignFor lang ftype (Proxy :: Proxy api) instance HasForeign lang ftype api @@ -511,14 +519,12 @@ instance where type Foreign ftype (IsSecure :> api) = Foreign ftype api - foreignFor lang ftype Proxy req = - foreignFor lang ftype (Proxy :: Proxy api) req + foreignFor lang ftype Proxy = foreignFor lang ftype (Proxy :: Proxy api) instance HasForeign lang ftype api => HasForeign lang ftype (Vault :> api) where type Foreign ftype (Vault :> api) = Foreign ftype api - foreignFor lang ftype Proxy req = - foreignFor lang ftype (Proxy :: Proxy api) req + foreignFor lang ftype Proxy = foreignFor lang ftype (Proxy :: Proxy api) instance HasForeign lang ftype api @@ -542,8 +548,7 @@ instance where type Foreign ftype (HttpVersion :> api) = Foreign ftype api - foreignFor lang ftype Proxy req = - foreignFor lang ftype (Proxy :: Proxy api) req + foreignFor lang ftype Proxy = foreignFor lang ftype (Proxy :: Proxy api) instance HasForeign lang ftype api @@ -551,8 +556,7 @@ instance where type Foreign ftype (Summary desc :> api) = Foreign ftype api - foreignFor lang ftype Proxy req = - foreignFor lang ftype (Proxy :: Proxy api) req + foreignFor lang ftype Proxy = foreignFor lang ftype (Proxy :: Proxy api) instance HasForeign lang ftype api @@ -560,14 +564,12 @@ instance where type Foreign ftype (Description desc :> api) = Foreign ftype api - foreignFor lang ftype Proxy req = - foreignFor lang ftype (Proxy :: Proxy api) req + foreignFor lang ftype Proxy = foreignFor lang ftype (Proxy :: Proxy api) instance HasForeign lang ftype (ToServantApi r) => HasForeign lang ftype (NamedRoutes r) where type Foreign ftype (NamedRoutes r) = Foreign ftype (ToServantApi r) - foreignFor lang ftype Proxy req = - foreignFor lang ftype (Proxy :: Proxy (ToServantApi r)) req + foreignFor lang ftype Proxy = foreignFor lang ftype (Proxy :: Proxy (ToServantApi r)) -- | Utility class used by 'listFromAPI' which computes -- the data needed to generate a function for each endpoint @@ -585,7 +587,7 @@ instance (GenerateList ftype rest, GenerateList ftype start) => GenerateList ftype (start :<|> rest) where - generateList (start :<|> rest) = (generateList start) ++ (generateList rest) + generateList (start :<|> rest) = generateList start ++ generateList rest -- | Generate the necessary data for codegen as a list, each 'Req' -- describing one endpoint from your API type. diff --git a/servant-http-streams/README.md b/servant-http-streams/README.md index 01e92696d..3ef051df5 100644 --- a/servant-http-streams/README.md +++ b/servant-http-streams/README.md @@ -40,5 +40,5 @@ main' = do Right books -> print books main :: IO () -main = return () +main = pure () ``` diff --git a/servant-http-streams/src/Servant/HttpStreams/Internal.hs b/servant-http-streams/src/Servant/HttpStreams/Internal.hs index 776e4c15b..4542cc6eb 100644 --- a/servant-http-streams/src/Servant/HttpStreams/Internal.hs +++ b/servant-http-streams/src/Servant/HttpStreams/Internal.hs @@ -1,5 +1,4 @@ {-# LANGUAGE CPP #-} -{-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} @@ -133,7 +132,7 @@ instance MonadBase IO ClientM where -- | Try clients in order, last error is preserved. instance Alt ClientM where - a b = a `catchError` \_ -> b + a b = a `catchError` const b instance RunClient ClientM where runRequestAcceptStatus = performRequest @@ -248,12 +247,12 @@ catchConnectionError action = fromInputStream :: Streams.InputStream b -> S.SourceT IO b fromInputStream is = S.SourceT $ \k -> k loop where - loop = S.Effect $ maybe S.Stop (flip S.Yield loop) <$> Streams.read is + loop = S.Effect $ maybe S.Stop (`S.Yield` loop) <$> Streams.read is toOutputStream :: S.SourceT IO BSL.ByteString -> Streams.OutputStream B.Builder -> IO () toOutputStream (S.SourceT k) os = k loop where - loop S.Stop = return () + loop S.Stop = pure () loop (S.Error err) = fail err loop (S.Skip s) = loop s loop (S.Effect mx) = mx >>= loop diff --git a/servant-http-streams/test/Servant/ClientSpec.hs b/servant-http-streams/test/Servant/ClientSpec.hs index 46d9a5b89..68efdd160 100644 --- a/servant-http-streams/test/Servant/ClientSpec.hs +++ b/servant-http-streams/test/Servant/ClientSpec.hs @@ -4,14 +4,12 @@ {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} -{-# LANGUAGE FunctionalDependencies #-} {-# LANGUAGE GADTs #-} +{-# LANGUAGE LambdaCase #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE PolyKinds #-} -{-# LANGUAGE RecordWildCards #-} {-# LANGUAGE ScopedTypeVariables #-} -{-# LANGUAGE StandaloneDeriving #-} {-# LANGUAGE TypeApplications #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeOperators #-} @@ -190,25 +188,25 @@ server :: Application server = serve api - ( return carol - :<|> return alice - :<|> return NoContent - :<|> (\name -> return $ Person name 0) - :<|> (\names -> return (zipWith Person names [0 ..])) - :<|> return - :<|> ( \name -> case name of - Just "alice" -> return alice + ( pure carol + :<|> pure alice + :<|> pure NoContent + :<|> (\name -> pure $ Person name 0) + :<|> (\names -> pure (zipWith Person names [0 ..])) + :<|> pure + :<|> ( \case + Just "alice" -> pure alice Just n -> throwError $ ServerError 400 (n ++ " not found") "" [] Nothing -> throwError $ ServerError 400 "missing parameter" "" [] ) - :<|> (\names -> return (zipWith Person names [0 ..])) - :<|> return - :<|> (Tagged $ \_request respond -> respond $ Wai.responseLBS HTTP.ok200 [] "rawSuccess") - :<|> (Tagged $ \_request respond -> respond $ Wai.responseLBS HTTP.badRequest400 [] "rawFailure") - :<|> (\a b c d -> return (a, b, c, d)) - :<|> (return $ addHeader 1729 $ addHeader "eg2" True) - :<|> return NoContent - :<|> (Tagged $ \_request respond -> respond $ Wai.responseLBS HTTP.found302 [("Location", "testlocation"), ("Set-Cookie", "testcookie=test")] "") + :<|> (\names -> pure (zipWith Person names [0 ..])) + :<|> pure + :<|> Tagged (\_request respond -> respond $ Wai.responseLBS HTTP.ok200 [] "rawSuccess") + :<|> Tagged (\_request respond -> respond $ Wai.responseLBS HTTP.badRequest400 [] "rawFailure") + :<|> (\a b c d -> pure (a, b, c, d)) + :<|> pure (addHeader 1729 $ addHeader "eg2" True) + :<|> pure NoContent + :<|> Tagged (\_request respond -> respond $ Wai.responseLBS HTTP.found302 [("Location", "testlocation"), ("Set-Cookie", "testcookie=test")] "") :<|> emptyServer ) @@ -224,9 +222,9 @@ failServer :: Application failServer = serve failApi - ( (Tagged $ \_request respond -> respond $ Wai.responseLBS HTTP.ok200 [] "") + ( Tagged (\_request respond -> respond $ Wai.responseLBS HTTP.ok200 [] "") :<|> (\_capture -> Tagged $ \_request respond -> respond $ Wai.responseLBS HTTP.ok200 [("content-type", "application/json")] "") - :<|> (Tagged $ \_request respond -> respond $ Wai.responseLBS HTTP.ok200 [("content-type", "fooooo")] "") + :<|> Tagged (\_request respond -> respond $ Wai.responseLBS HTTP.ok200 [("content-type", "fooooo")] "") ) -- * basic auth stuff @@ -241,15 +239,15 @@ basicAuthHandler :: BasicAuthCheck () basicAuthHandler = let check (BasicAuthData username password) = if username == "servant" && password == "server" - then return (Authorized ()) - else return Unauthorized + then pure (Authorized ()) + else pure Unauthorized in BasicAuthCheck check basicServerContext :: Context '[BasicAuthCheck ()] basicServerContext = basicAuthHandler :. EmptyContext basicAuthServer :: Application -basicAuthServer = serveWithContext basicAuthAPI basicServerContext (const (return alice)) +basicAuthServer = serveWithContext basicAuthAPI basicServerContext (const (pure alice)) -- * general auth stuff @@ -267,14 +265,14 @@ genAuthHandler :: AuthHandler Wai.Request () genAuthHandler = let handler req = case lookup "AuthHeader" (Wai.requestHeaders req) of Nothing -> throwError (err401{errBody = "Missing auth header"}) - Just _ -> return () + Just _ -> pure () in mkAuthHandler handler genAuthServerContext :: Context '[AuthHandler Wai.Request ()] genAuthServerContext = genAuthHandler :. EmptyContext genAuthServer :: Application -genAuthServer = serveWithContext genAuthAPI genAuthServerContext (const (return alice)) +genAuthServer = serveWithContext genAuthAPI genAuthServerContext (const (pure alice)) runClient :: NFData a => ClientM a -> BaseUrl -> IO (Either ClientError a) runClient x burl = withClientEnvIO burl (runClientM x) @@ -282,7 +280,7 @@ runClient x burl = withClientEnvIO burl (runClientM x) runClientUnsafe :: ClientM a -> BaseUrl -> IO (Either ClientError a) runClientUnsafe x burl = withClientEnvIO burl (runClientMUnsafe x) where - runClientMUnsafe x env = withClientM x env return + runClientMUnsafe x env = withClientM x env pure successSpec :: Spec successSpec = beforeAll (startWaiApp server) $ afterAll endWaiApp $ do @@ -303,7 +301,7 @@ successSpec = beforeAll (startWaiApp server) $ afterAll endWaiApp $ do left show <$> runClient (getCapture "Paula") baseUrl `shouldReturn` Right (Person "Paula" 0) it "Servant.API.CaptureAll" $ \(_, baseUrl) -> do - let expected = [(Person "Paula" 0), (Person "Peta" 1)] + let expected = [Person "Paula" 0, Person "Peta" 1] left show <$> runClient (getCaptureAll ["Paula", "Peta"]) baseUrl `shouldReturn` Right expected it "Servant.API.ReqBody" $ \(_, baseUrl) -> do @@ -359,7 +357,7 @@ successSpec = beforeAll (startWaiApp server) $ afterAll endWaiApp $ do property $ forAllShrink pathGen shrink $ \(NonEmpty cap) num flag body -> ioProperty $ do result <- left show <$> runClient (getMultiple cap num flag body) baseUrl - return $ + pure $ result === Right (cap, num, flag, body) wrappedApiSpec :: Spec @@ -372,13 +370,14 @@ wrappedApiSpec = describe "error status codes" $ do let getResponse :: ClientM () getResponse = client api Left (FailureResponse _ r) <- runClient getResponse baseUrl - responseStatusCode r `shouldBe` (HTTP.Status 500 "error message") - in mapM_ test $ - (WrappedApi (Proxy :: Proxy (Delete '[JSON] ())), "Delete") - : (WrappedApi (Proxy :: Proxy (Get '[JSON] ())), "Get") - : (WrappedApi (Proxy :: Proxy (Post '[JSON] ())), "Post") - : (WrappedApi (Proxy :: Proxy (Put '[JSON] ())), "Put") - : [] + responseStatusCode r `shouldBe` HTTP.Status 500 "error message" + in mapM_ + test + [ (WrappedApi (Proxy :: Proxy (Delete '[JSON] ())), "Delete") + , (WrappedApi (Proxy :: Proxy (Get '[JSON] ())), "Get") + , (WrappedApi (Proxy :: Proxy (Post '[JSON] ())), "Post") + , (WrappedApi (Proxy :: Proxy (Put '[JSON] ())), "Put") + ] failSpec :: Spec failSpec = beforeAll (startWaiApp failServer) $ afterAll endWaiApp $ do @@ -387,14 +386,14 @@ failSpec = beforeAll (startWaiApp failServer) $ afterAll endWaiApp $ do let (_ :<|> _ :<|> getDeleteEmpty :<|> _) = client api Left res <- runClient getDeleteEmpty baseUrl case res of - FailureResponse _ r | responseStatusCode r == HTTP.status404 -> return () + FailureResponse _ r | responseStatusCode r == HTTP.status404 -> pure () _ -> fail $ "expected 404 response, but got " <> show res it "reports DecodeFailure" $ \(_, baseUrl) -> do let (_ :<|> _ :<|> _ :<|> getCapture :<|> _) = client api Left res <- runClient (getCapture "foo") baseUrl case res of - DecodeFailure _ _ -> return () + DecodeFailure _ _ -> pure () _ -> fail $ "expected DecodeFailure, but got " <> show res -- we don't catch IOException's @@ -402,21 +401,21 @@ failSpec = beforeAll (startWaiApp failServer) $ afterAll endWaiApp $ do let (getGetWrongHost :<|> _) = client api Left res <- runClient getGetWrongHost (BaseUrl Http "127.0.0.1" 19872 "") case res of - ConnectionError _ -> return () + ConnectionError _ -> pure () _ -> fail $ "expected ConnectionError, but got " <> show res it "reports UnsupportedContentType" $ \(_, baseUrl) -> do let (_ :<|> getGet :<|> _) = client api Left res <- runClient getGet baseUrl case res of - UnsupportedContentType ("application/octet-stream") _ -> return () + UnsupportedContentType "application/octet-stream" _ -> pure () _ -> fail $ "expected UnsupportedContentType, but got " <> show res it "reports InvalidContentTypeHeader" $ \(_, baseUrl) -> do let (_ :<|> _ :<|> _ :<|> _ :<|> _ :<|> getBody :<|> _) = client api Left res <- runClient (getBody alice) baseUrl case res of - InvalidContentTypeHeader _ -> return () + InvalidContentTypeHeader _ -> pure () _ -> fail $ "expected InvalidContentTypeHeader, but got " <> show res data WrappedApi where @@ -457,7 +456,7 @@ genAuthSpec = beforeAll (startWaiApp genAuthServer) $ afterAll endWaiApp $ do let getProtected = client genAuthAPI let authRequest = Auth.mkAuthenticatedRequest () (\_ req -> Req.addHeader "Wrong" ("header" :: String) req) Left (FailureResponse _ r) <- runClient (getProtected authRequest) baseUrl - responseStatusCode r `shouldBe` (HTTP.Status 401 "Unauthorized") + responseStatusCode r `shouldBe` HTTP.Status 401 "Unauthorized" -- * hoistClient @@ -467,7 +466,7 @@ hoistClientAPI :: Proxy HoistClientAPI hoistClientAPI = Proxy hoistClientServer :: Application -- implements HoistClientAPI -hoistClientServer = serve hoistClientAPI $ return 5 :<|> (\n -> return n) +hoistClientServer = serve hoistClientAPI $ pure 5 :<|> pure hoistClientSpec :: Spec hoistClientSpec = beforeAll (startWaiApp hoistClientServer) $ afterAll endWaiApp $ do @@ -503,9 +502,9 @@ connectionErrorSpec = describe "Servant.Client.ClientError" $ startWaiApp :: Application -> IO (ThreadId, BaseUrl) startWaiApp app = do (port, socket) <- openTestSocket - let settings = setPort port $ defaultSettings + let settings = setPort port defaultSettings thread <- forkIO $ runSettingsSocket settings socket app - return (thread, BaseUrl Http "127.0.0.1" port "") + pure (thread, BaseUrl Http "127.0.0.1" port "") endWaiApp :: (ThreadId, BaseUrl) -> IO () endWaiApp (thread, _) = killThread thread @@ -517,7 +516,7 @@ openTestSocket = do bind s (SockAddrInet defaultPort localhost) listen s 1 port <- socketPort s - return (fromIntegral port, s) + pure (fromIntegral port, s) pathGen :: Gen (NonEmptyList Char) pathGen = fmap NonEmpty path diff --git a/servant-http-streams/test/Servant/StreamSpec.hs b/servant-http-streams/test/Servant/StreamSpec.hs index 3982b30f3..3fc4cd1b1 100644 --- a/servant-http-streams/test/Servant/StreamSpec.hs +++ b/servant-http-streams/test/Servant/StreamSpec.hs @@ -1,17 +1,13 @@ {-# LANGUAGE CPP #-} {-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE DataKinds #-} -{-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} -{-# LANGUAGE FunctionalDependencies #-} {-# LANGUAGE GADTs #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE PolyKinds #-} -{-# LANGUAGE RecordWildCards #-} {-# LANGUAGE ScopedTypeVariables #-} -{-# LANGUAGE StandaloneDeriving #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeOperators #-} {-# LANGUAGE UndecidableInstances #-} @@ -74,11 +70,11 @@ bob = Person "Bob" 25 server :: Application server = serve api $ - return (source [alice, bob, alice]) - :<|> return (source [alice, bob, alice]) + pure (source [alice, bob, alice]) + :<|> pure (source [alice, bob, alice]) -- 2 ^ (18 + 10) = 256M - :<|> return (SourceT ($ lots (powerOfTwo 18))) - :<|> return + :<|> pure (SourceT ($ lots (powerOfTwo 18))) + :<|> pure where lots n | n < 0 = Stop @@ -86,7 +82,7 @@ server = let size = powerOfTwo 10 mbs <- getHardwareEntropy size bs <- maybe (getEntropy size) pure mbs - return (Yield bs (lots (n - 1))) + pure (Yield bs (lots (n - 1))) powerOfTwo :: Int -> Int powerOfTwo = (2 ^) diff --git a/servant-machines/example/Main.hs b/servant-machines/example/Main.hs index 78c2192dd..257e74439 100644 --- a/servant-machines/example/Main.hs +++ b/servant-machines/example/Main.hs @@ -1,5 +1,5 @@ {-# LANGUAGE DataKinds #-} -{-# LANGUAGE DeriveGeneric #-} +{-# LANGUAGE LambdaCase #-} {-# LANGUAGE TypeOperators #-} module Main (main) where @@ -39,26 +39,26 @@ server = fast :<|> slow :<|> proxy where fast n = liftIO $ do putStrLn ("/get/" ++ show n) - return $ fastMachine n + pure $ fastMachine n slow n = liftIO $ do putStrLn ("/slow/" ++ show n) - return $ slowMachine n + pure $ slowMachine n proxy c = liftIO $ do putStrLn "/proxy" - return c + pure c -- for some reason unfold leaks? fastMachine m - | m < 0 = MachineT (return Stop) - | otherwise = MachineT (return (Yield m (fastMachine (m - 1)))) + | m < 0 = MachineT (pure Stop) + | otherwise = MachineT (pure (Yield m (fastMachine (m - 1)))) slowMachine m - | m < 0 = MachineT (return Stop) + | m < 0 = MachineT (pure Stop) | otherwise = MachineT $ do threadDelay 1000000 - return (Yield m (slowMachine (m - 1))) + pure (Yield m (slowMachine (m - 1))) app :: Application app = serve api server @@ -78,7 +78,7 @@ main = do n <- maybe (fail $ "not a number: " ++ ns) pure $ readMaybe ns mgr <- newManager defaultManagerSettings burl <- parseBaseUrl "http://localhost:8000/" - withClientM (cli n) (mkClientEnv mgr burl) $ \me -> case me of + withClientM (cli n) (mkClientEnv mgr burl) $ \case Left err -> print err Right m -> do x <- runT $ fold (\p _ -> p + 1) (0 :: Int) <~ m diff --git a/servant-machines/src/Servant/Machines.hs b/servant-machines/src/Servant/Machines.hs index 241fbafe8..b1f0e744d 100644 --- a/servant-machines/src/Servant/Machines.hs +++ b/servant-machines/src/Servant/Machines.hs @@ -28,20 +28,20 @@ instance MachineToSourceIO IO where go (MachineT m) = S.Effect $ do step <- m case step of - Stop -> return S.Stop - Yield x m' -> return (S.Yield x (go m')) - Await _ _ m' -> return (S.Skip (go m')) + Stop -> pure S.Stop + Yield x m' -> pure (S.Yield x (go m')) + Await _ _ m' -> pure (S.Skip (go m')) instance MachineToSourceIO m => ToSourceIO o (MachineT m k o) where toSourceIO = machineToSourceIO instance MonadIO m => FromSourceIO o (MachineT m k o) where - fromSourceIO src = return $ MachineT $ liftIO $ S.unSourceT src go + fromSourceIO src = pure $ MachineT $ liftIO $ S.unSourceT src go where go :: S.StepT IO o -> IO (Step k o (MachineT m k o)) - go S.Stop = return Stop + go S.Stop = pure Stop go (S.Error err) = fail err go (S.Skip s) = go s go (S.Effect ms) = ms >>= go - go (S.Yield x s) = return (Yield x (MachineT (liftIO (go s)))) + go (S.Yield x s) = pure (Yield x (MachineT (liftIO (go s)))) {-# SPECIALIZE INLINE fromSourceIO :: SourceIO o -> IO (MachineT IO k o) #-} diff --git a/servant-pipes/example/Main.hs b/servant-pipes/example/Main.hs index aae1e8150..81cf225bb 100644 --- a/servant-pipes/example/Main.hs +++ b/servant-pipes/example/Main.hs @@ -1,5 +1,5 @@ {-# LANGUAGE DataKinds #-} -{-# LANGUAGE DeriveGeneric #-} +{-# LANGUAGE LambdaCase #-} {-# LANGUAGE TypeOperators #-} module Main (main) where @@ -47,23 +47,23 @@ server = fast :<|> slow :<|> readme :<|> proxy where fast n = liftIO $ do putStrLn ("/get/" ++ show n) - return $ fastPipe n + pure $ fastPipe n slow n = liftIO $ do putStrLn ("/slow/" ++ show n) - return $ slowPipe n + pure $ slowPipe n readme = liftIO $ do putStrLn "/readme" - return $ P.withFile "README.md" ReadMode $ \h -> PBS.fromHandle h + pure $ P.withFile "README.md" ReadMode $ \h -> PBS.fromHandle h proxy c = liftIO $ do putStrLn "/proxy" - return c + pure c -- for some reason unfold leaks? fastPipe m - | m < 0 = return () + | m < 0 = pure () | otherwise = P.yield m >> fastPipe (m - 1) slowPipe m = fastPipe m P.>-> P.mapM (<$ threadDelay 1000000) @@ -86,7 +86,7 @@ main = do n <- maybe (fail $ "not a number: " ++ ns) pure $ readMaybe ns mgr <- newManager defaultManagerSettings burl <- parseBaseUrl "http://localhost:8000/" - withClientM (cli n) (mkClientEnv mgr burl) $ \me -> case me of + withClientM (cli n) (mkClientEnv mgr burl) $ \case Left err -> print err Right p -> do x <- P.fold (\c _ -> c + 1) (0 :: Int) id p diff --git a/servant-pipes/src/Servant/Pipes.hs b/servant-pipes/src/Servant/Pipes.hs index e06be5817..a53a79c26 100644 --- a/servant-pipes/src/Servant/Pipes.hs +++ b/servant-pipes/src/Servant/Pipes.hs @@ -64,7 +64,7 @@ instance (MonadIO m, a ~ (), a' ~ X, b' ~ (), r ~ ()) => FromSourceIO b (Proxy a' a b' b m r) where - fromSourceIO src = pure $ M $ liftIO $ S.unSourceT src (return . go) + fromSourceIO src = pure $ M $ liftIO $ S.unSourceT src (pure . go) where go :: S.StepT IO b -> Proxy X () () b m () go S.Stop = Pure () diff --git a/servant-quickcheck/doc/posts/src/Main.hs b/servant-quickcheck/doc/posts/src/Main.hs index 8c8247dff..c824e9314 100644 --- a/servant-quickcheck/doc/posts/src/Main.hs +++ b/servant-quickcheck/doc/posts/src/Main.hs @@ -51,24 +51,24 @@ server conn = liftIO (lookupSpecies conn sname) :<|> liftIO (deleteSpecies conn sname) ) - :<|> (\species -> liftIO $ insertSpecies conn species) + :<|> (liftIO . insertSpecies conn) ) - :<|> (liftIO $ allSpecies conn) + :<|> liftIO (allSpecies conn) lookupSpecies :: Connection -> Text -> IO Species lookupSpecies conn name = do [s] <- query conn "SELECT * FROM species WHERE species_name = ?" (Only name) - return s + pure s deleteSpecies :: Connection -> Text -> IO () deleteSpecies conn name = do _ <- execute conn "DELETE FROM species WHERE species_name = ?" (Only name) - return () + pure () insertSpecies :: Connection -> Species -> IO () insertSpecies conn Species{..} = do _ <- execute conn "INSERT INTO species (species_name, species_genus) VALUES (?)" (speciesName, speciesGenus) - return () + pure () allSpecies :: Connection -> IO [Species] allSpecies conn = do diff --git a/servant-quickcheck/doc/posts/src/Spec.hs b/servant-quickcheck/doc/posts/src/Spec.hs index 14ce3b0a8..4b70d5e30 100644 --- a/servant-quickcheck/doc/posts/src/Spec.hs +++ b/servant-quickcheck/doc/posts/src/Spec.hs @@ -13,7 +13,7 @@ spec :: Spec spec = describe "the species application" $ beforeAll check $ do let pserver = do conn <- connectPostgreSQL "dbname=servant-quickcheck" - return $ server conn + pure $ server conn it "should not return 500s" $ do withServantServer api pserver $ \url -> diff --git a/servant-quickcheck/example/Main.hs b/servant-quickcheck/example/Main.hs index 6ac064cf6..61c1d2937 100644 --- a/servant-quickcheck/example/Main.hs +++ b/servant-quickcheck/example/Main.hs @@ -25,10 +25,10 @@ api :: Proxy API api = Proxy server :: Server API -server = return "Sigurð Fáfnirslayer" +server = pure "Sigurð Fáfnirslayer" spec :: Spec spec = describe "example server" $ it "mangles UTF-8 in error messages" $ - withServantServer api (return server) $ \burl -> + withServantServer api (pure server) $ \burl -> serverSatisfies api burl defaultArgs (getsHaveCacheControlHeader <%> mempty) diff --git a/servant-quickcheck/src/Servant/QuickCheck/Internal/HasGenRequest.hs b/servant-quickcheck/src/Servant/QuickCheck/Internal/HasGenRequest.hs index a7eb619a5..cd447384d 100644 --- a/servant-quickcheck/src/Servant/QuickCheck/Internal/HasGenRequest.hs +++ b/servant-quickcheck/src/Servant/QuickCheck/Internal/HasGenRequest.hs @@ -65,7 +65,7 @@ instance (HasGenRequest b, KnownSymbol path) => HasGenRequest (path :> b) where ( oldf , do old' <- old - return $ \burl -> + pure $ \burl -> let r = old' burl oldPath = path r oldPath' = BS.dropWhile (== BS.c2w '/') oldPath @@ -93,7 +93,7 @@ instance , do old' <- old new' <- toUrlPiece <$> new - return $ \burl -> let r = old' burl in r{path = Text.encodeUtf8 new' <> path r} + pure $ \burl -> let r = old' burl in r{path = Text.encodeUtf8 new' <> path r} ) where (oldf, old) = genRequest (Proxy :: Proxy b) @@ -109,7 +109,7 @@ instance old' <- old new' <- fmap (Text.encodeUtf8 . toUrlPiece) <$> new let new'' = BS.intercalate "/" new' - return $ \burl -> let r = old' burl in r{path = new'' <> path r} + pure $ \burl -> let r = old' burl in r{path = new'' <> path r} ) where (oldf, old) = genRequest (Proxy :: Proxy b) @@ -124,7 +124,7 @@ instance , do old' <- old new' <- toUrlPiece <$> new -- TODO: generate lenient or/and optional - return $ \burl -> + pure $ \burl -> let r = old' burl in r { requestHeaders = (hdr, Text.encodeUtf8 new') : requestHeaders r @@ -145,7 +145,7 @@ instance old' <- old -- TODO: generate lenient new' <- new (ct, bd) <- elements $ allMimeRender (Proxy :: Proxy x) new' - return $ \burl -> + pure $ \burl -> let r = old' burl in r { requestBody = RequestBodyLBS bd @@ -165,7 +165,7 @@ instance , do new' <- new -- TODO: generate lenient or/and optional old' <- old - return $ \burl -> + pure $ \burl -> let r = old' burl newExpr = param <> "=" <> Text.encodeUtf8 (toQueryParam new') qs = queryString r @@ -187,12 +187,12 @@ instance , do new' <- new old' <- old - return $ \burl -> + pure $ \burl -> let r = old' burl in r { queryString = queryString r - <> if not (null new') then fold (toParam <$> new') else "" + <> if not (null new') then joinAmp (toParam <$> new') else "" } ) where @@ -200,7 +200,7 @@ instance param = BS8.pack $ symbolVal (Proxy :: Proxy x) new = arbitrary :: Gen [c] toParam c = param <> "[]=" <> Text.encodeUtf8 (toQueryParam c) - fold = foldr1 (\a b -> a <> "&" <> b) + joinAmp = foldr1 (\a b -> a <> "&" <> b) instance (HasGenRequest b, KnownSymbol x) @@ -210,7 +210,7 @@ instance ( oldf , do old' <- old - return $ \burl -> + pure $ \burl -> let r = old' burl qs = queryString r in r @@ -227,7 +227,7 @@ instance where genRequest _ = ( 1 - , return $ \burl -> + , pure $ \burl -> defaultRequest { host = BS8.pack $ baseUrlHost burl , port = baseUrlPort burl @@ -242,7 +242,7 @@ instance where genRequest _ = ( 1 - , return $ \burl -> + , pure $ \burl -> defaultRequest { host = BS8.pack $ baseUrlHost burl , port = baseUrlPort burl diff --git a/servant-quickcheck/src/Servant/QuickCheck/Internal/Predicates.hs b/servant-quickcheck/src/Servant/QuickCheck/Internal/Predicates.hs index 469df3d70..89367ec84 100644 --- a/servant-quickcheck/src/Servant/QuickCheck/Internal/Predicates.hs +++ b/servant-quickcheck/src/Servant/QuickCheck/Internal/Predicates.hs @@ -73,7 +73,7 @@ notLongerThan maxAllowed = when (toNanoSecs (end `diffTimeSpec` start) > maxAllowed) $ throw $ PredicateFailure "notLongerThan" (Just req) resp - return [] + pure [] -- | [__Best Practice__] -- @@ -101,11 +101,11 @@ onlyJsonObjects = ResponsePredicate ( \resp -> do case lookup "content-type" (first foldedCase <$> responseHeaders resp) of - Nothing -> return () + Nothing -> pure () Just ctype -> when ("application/json" `SBS.isPrefixOf` ctype) $ do case (decode (responseBody resp) :: Maybe Object) of Nothing -> throw $ PredicateFailure "onlyJsonObjects" Nothing resp - Just _ -> return () + Just _ -> pure () ) -- | __Optional__ @@ -140,8 +140,8 @@ createContainsValidLocation = Just x -> do resp2 <- httpLbs x mgr status2XX (Just req) resp2 n - return [resp, resp2] - else return [resp] + pure [resp, resp2] + else pure [resp] -- | [__Optional__] -- @@ -176,8 +176,8 @@ getsHaveLastModifiedHeader = resp <- httpLbs req mgr unless (hasValidHeader "Last-Modified" isRFC822Date resp) $ do throw $ PredicateFailure "getsHaveLastModifiedHeader" (Just req) resp - return [resp] - else return [] + pure [resp] + else pure [] -- | [__RFC Compliance__] -- @@ -208,7 +208,7 @@ notAllowedContainsAllowHeader = case filter pred' (zip reqs resp) of (x : _) -> throw $ PredicateFailure "notAllowedContainsAllowHeader" (Just $ fst x) (snd x) - [] -> return resp + [] -> pure resp where pred' (_, resp) = responseStatus resp == status405 && not (hasValidHeader "Allow" go resp) where @@ -240,7 +240,7 @@ honoursAcceptHeader = sacc = fromMaybe "*/*" $ lookup "Accept" (requestHeaders req) ( if (status100 < scode && scode < status300) && isJust (sctype >>= \x -> matchAccept [x] sacc) then throw $ PredicateFailure "honoursAcceptHeader" (Just req) resp - else return [resp] + else pure [resp] ) -- | [__Best Practice__] @@ -265,8 +265,8 @@ getsHaveCacheControlHeader = resp <- httpLbs req mgr unless (hasValidHeader "Cache-Control" (const True) resp) $ do throw $ PredicateFailure "getsHaveCacheControlHeader" (Just req) resp - return [resp] - else return [] + pure [resp] + else pure [] -- | [__Best Practice__] -- @@ -282,8 +282,8 @@ headsHaveCacheControlHeader = unless (hasValidHeader "Cache-Control" (const True) resp) $ throw $ PredicateFailure "headsHaveCacheControlHeader" (Just req) resp - return [resp] - else return [] + pure [resp] + else pure [] {- -- | @@ -395,7 +395,7 @@ instance Semigroup ResponsePredicate where ResponsePredicate a <> ResponsePredicate b = ResponsePredicate $ \x -> a x >> b x instance Monoid ResponsePredicate where - mempty = ResponsePredicate $ const $ return () + mempty = ResponsePredicate $ const $ pure () mappend = (<>) -- | A predicate that depends on both the request and the response. @@ -408,7 +408,7 @@ newtype RequestPredicate = RequestPredicate -- TODO: This isn't actually a monoid instance Monoid RequestPredicate where - mempty = RequestPredicate (\r m -> httpLbs r m >>= \x -> return [x]) + mempty = RequestPredicate (\r m -> httpLbs r m >>= \x -> pure [x]) mappend = (<>) -- TODO: This isn't actually a monoid @@ -454,12 +454,12 @@ instance JoinPreds ResponsePredicate where infixr 6 <%> finishPredicates :: Predicates -> Request -> Manager -> IO (Maybe PredicateFailure) -finishPredicates p req mgr = go `catch` \(e :: PredicateFailure) -> return $ Just e +finishPredicates p req mgr = go `catch` \(e :: PredicateFailure) -> pure $ Just e where go = do resps <- getRequestPredicate (requestPredicates p) req mgr mapM_ (getResponsePredicate $ responsePredicates p) resps - return Nothing + pure Nothing -- * helpers @@ -475,5 +475,5 @@ isRFC822Date s = status2XX :: Monad m => Maybe Request -> Response LBS.ByteString -> T.Text -> m () status2XX mreq resp t | status200 <= responseStatus resp && responseStatus resp < status300 = - return () + pure () | otherwise = throw $ PredicateFailure t mreq resp diff --git a/servant-quickcheck/src/Servant/QuickCheck/Internal/QuickCheck.hs b/servant-quickcheck/src/Servant/QuickCheck/Internal/QuickCheck.hs index 9b8cadac0..ec687a4cb 100644 --- a/servant-quickcheck/src/Servant/QuickCheck/Internal/QuickCheck.hs +++ b/servant-quickcheck/src/Servant/QuickCheck/Internal/QuickCheck.hs @@ -98,7 +98,7 @@ serversEqual api burl1 burl2 args req = do _ <- run $ tryPutMVar deetsMVar $ ServerEqualityFailure req1 resp1 resp2 assert False case r of - Success{} -> return () + Success{} -> pure () Failure{} -> do mx <- tryReadMVar deetsMVar case mx of @@ -163,9 +163,9 @@ serverSatisfiesMgr api manager burl args preds = do _ <- run $ tryPutMVar deetsMVar v case v of Just _ -> assert False - _ -> return () + _ -> pure () case r of - Success{} -> return () + Success{} -> pure () Failure{} -> do mx <- tryReadMVar deetsMVar case mx of @@ -203,7 +203,7 @@ serverDoesntSatisfyMgr api manager burl args preds = do v <- run $ finishPredicates preds (noCheckStatus req) manager assert $ not $ null v case r of - Success{} -> return () + Success{} -> pure () GaveUp{numTests = n} -> expectationFailure $ "Gave up after " ++ show n ++ " tests" Failure{output = m} -> expectationFailure $ "Failed:\n" ++ show m NoExpectedFailure{} -> expectationFailure "No expected failure" diff --git a/servant-quickcheck/test/Servant/QuickCheck/InternalSpec.hs b/servant-quickcheck/test/Servant/QuickCheck/InternalSpec.hs index 586a054a2..9f7794d59 100644 --- a/servant-quickcheck/test/Servant/QuickCheck/InternalSpec.hs +++ b/servant-quickcheck/test/Servant/QuickCheck/InternalSpec.hs @@ -8,6 +8,7 @@ import Control.Monad (replicateM) import Control.Monad.IO.Class (liftIO) import qualified Data.ByteString as BS import qualified Data.ByteString.Char8 as C +import Data.Functor import Data.Maybe (fromJust) import Network.HTTP.Client (path, queryString) import Prelude.Compat @@ -173,8 +174,8 @@ deepPathSpec = describe "Path components" $ do let rng = mkQCGen 0 burl = BaseUrl Http "localhost" 80 "" gen = runGenRequest deepAPI - req = (unGen gen rng 0) burl - path req `shouldBe` ("/one/two/three") + req = unGen gen rng 0 burl + path req `shouldBe` "/one/two/three" queryParamsSpec :: Spec queryParamsSpec = describe "QueryParams" $ do @@ -182,7 +183,7 @@ queryParamsSpec = describe "QueryParams" $ do let rng = mkQCGen 0 burl = BaseUrl Http "localhost" 80 "" gen = runGenRequest paramsAPI - req = (unGen gen rng 0) burl + req = unGen gen rng 0 burl qs = C.unpack $ queryString req qs `shouldBe` "one=_&two=_" @@ -192,7 +193,7 @@ queryFlagsSpec = describe "QueryFlags" $ do let rng = mkQCGen 0 burl = BaseUrl Http "localhost" 80 "" gen = runGenRequest flagsAPI - req = (unGen gen rng 0) burl + req = unGen gen rng 0 burl qs = C.unpack $ queryString req qs `shouldBe` "one&two" @@ -232,9 +233,9 @@ unbiasedGenerationSpec = describe "Unbiased Generation of requests" let burl = BaseUrl Http "localhost" 80 "" let runs = 10000 :: Double someRequests <- replicateM 10000 (makeRandomRequest largeApi burl) - let mean = (sum $ map fromIntegral someRequests) / runs + let mean = sum (map fromIntegral someRequests) / runs let variancer x = let ix = fromIntegral x in (ix - mean) * (ix - mean) - let variance = (sum $ map variancer someRequests) / runs - 1 + let variance = sum (map variancer someRequests) / runs - 1 -- mean should be around 8.5. If this fails, we likely need more runs (or there's a bug!) mean > 8 `shouldBe` True mean < 9 `shouldBe` True @@ -266,9 +267,9 @@ flagsAPI = Proxy server :: IO (Server API) server = do mvar <- newMVar "" - return $ (\x -> liftIO $ swapMVar mvar x) - :<|> (liftIO $ readMVar mvar >>= return . length) - :<|> (const $ return ()) + pure $ (liftIO . swapMVar mvar) + :<|> liftIO (readMVar mvar <&> length) + :<|> const (pure ()) type API2 = "failplz" :> Get '[JSON] Int @@ -281,13 +282,13 @@ deepAPI :: Proxy DeepAPI deepAPI = Proxy server2 :: IO (Server API2) -server2 = return $ return 1 +server2 = pure $ pure 1 server3 :: IO (Server API2) -server3 = return $ return 2 +server3 = pure $ pure 2 serverFailing :: IO (Server API2) -serverFailing = return . throwError $ err405 +serverFailing = pure . throwError $ err405 -- With Doctypes type HtmlDoctype = Get '[HTML] Blaze.Html @@ -329,7 +330,7 @@ octetAPI :: Proxy OctetAPI octetAPI = Proxy serverOctetAPI :: IO (Server OctetAPI) -serverOctetAPI = return $ return "blah" +serverOctetAPI = pure $ pure "blah" type JsonApi = "jsonComparison" :> Get '[OctetStream] BS.ByteString @@ -337,19 +338,19 @@ jsonApi :: Proxy JsonApi jsonApi = Proxy jsonServer1 :: IO (Server JsonApi) -jsonServer1 = return $ return "{ \"b\": [\"b\"], \"a\": 1 }" -- whitespace, ordering different +jsonServer1 = pure $ pure "{ \"b\": [\"b\"], \"a\": 1 }" -- whitespace, ordering different jsonServer2 :: IO (Server JsonApi) -jsonServer2 = return $ return "{\"a\": 1,\"b\":[\"b\"]}" +jsonServer2 = pure $ pure "{\"a\": 1,\"b\":[\"b\"]}" jsonServer3 :: IO (Server JsonApi) -jsonServer3 = return $ return "{\"a\": 2, \"b\": [\"b\"]}" +jsonServer3 = pure $ pure "{\"a\": 2, \"b\": [\"b\"]}" jsonServer4 :: IO (Server JsonApi) -jsonServer4 = return $ return "{\"c\": 1, \"d\": [\"b\"]}" +jsonServer4 = pure $ pure "{\"c\": 1, \"d\": [\"b\"]}" ctx :: Context '[BasicAuthCheck ()] -ctx = BasicAuthCheck (const . return $ NoSuchUser) :. EmptyContext +ctx = BasicAuthCheck (const . pure $ NoSuchUser) :. EmptyContext ------------------------------------------------------------------------------ -- Utils @@ -358,11 +359,11 @@ evalExample :: (Arg e ~ (), Example e) => e -> IO EvalResult evalExample e = do r <- safeEvaluateExample e defaultParams ($ ()) progCallback case resultStatus r of - Success -> return $ AllGood - Failure _ reason -> return $ FailedWith $ show reason + Success -> pure AllGood + Failure _ reason -> pure $ FailedWith $ show reason Pending{} -> error "should not happen" where - progCallback _ = return () + progCallback _ = pure () data EvalResult = AnException SomeException @@ -374,8 +375,4 @@ args :: Args args = defaultArgs{maxSuccess = noOfTestCases} noOfTestCases :: Int -#if LONG_TESTS -noOfTestCases = 20000 -#else noOfTestCases = 1000 -#endif diff --git a/servant-server/example/greet.hs b/servant-server/example/greet.hs index ee7632fd1..2812432ba 100644 --- a/servant-server/example/greet.hs +++ b/servant-server/example/greet.hs @@ -63,12 +63,12 @@ server = helloH :<|> postGreetH :<|> deleteGreetH :<|> otherRoutes version = pure 42 helloH name Nothing = helloH name (Just False) - helloH name (Just False) = return . Greet $ "Hello, " <> name - helloH name (Just True) = return . Greet . toUpper $ "Hello, " <> name + helloH name (Just False) = pure . Greet $ "Hello, " <> name + helloH name (Just True) = pure . Greet . toUpper $ "Hello, " <> name - postGreetH greet = return greet + postGreetH = pure - deleteGreetH _ = return NoContent + deleteGreetH _ = pure NoContent -- Turn the server into a WAI app. 'serve' is provided by servant, -- more precisely by the Servant.Server module. diff --git a/servant-server/src/Servant/Server/Experimental/Auth.hs b/servant-server/src/Servant/Server/Experimental/Auth.hs index 43f4c8f1e..57200af9a 100644 --- a/servant-server/src/Servant/Server/Experimental/Auth.hs +++ b/servant-server/src/Servant/Server/Experimental/Auth.hs @@ -13,6 +13,7 @@ module Servant.Server.Experimental.Auth where +import Control.Monad import Control.Monad.Trans (liftIO) import Data.Kind (Type) import Data.Proxy (Proxy (Proxy)) @@ -72,4 +73,4 @@ instance authHandler :: Request -> Handler (AuthServerData (AuthProtect tag)) authHandler = unAuthHandler (getContextEntry context) authCheck :: Request -> DelayedIO (AuthServerData (AuthProtect tag)) - authCheck = (>>= either delayedFailFatal return) . liftIO . runHandler . authHandler + authCheck = either delayedFailFatal pure <=< (liftIO . runHandler . authHandler) diff --git a/servant-server/src/Servant/Server/Internal.hs b/servant-server/src/Servant/Server/Internal.hs index 790cfbf4a..135d83fee 100644 --- a/servant-server/src/Servant/Server/Internal.hs +++ b/servant-server/src/Servant/Server/Internal.hs @@ -1,5 +1,4 @@ {-# LANGUAGE CPP #-} -{-# LANGUAGE EmptyCase #-} module Servant.Server.Internal ( module Servant.Server.Internal @@ -256,8 +255,8 @@ instance , parseUrlPiece txt :: Either T.Text a ) of (SFalse, Left e) -> delayedFail $ formatError rep request $ T.unpack e - (SFalse, Right v) -> return v - (STrue, piece) -> return $ either (Left . T.unpack) Right piece + (SFalse, Right v) -> pure v + (STrue, piece) -> pure $ either (Left . T.unpack) Right piece ) where rep = typeRep (Proxy :: Proxy Capture') @@ -304,7 +303,7 @@ instance ( addCapture d $ \txts -> withRequest $ \request -> case parseUrlPieces txts of Left e -> delayedFail $ formatError rep request $ T.unpack e - Right v -> return v + Right v -> pure v ) where rep = typeRep (Proxy :: Proxy CaptureAll) @@ -354,7 +353,7 @@ allowedMethod method request = allowedMethodHead method request || requestMethod methodCheck :: Method -> Request -> DelayedIO () methodCheck method request - | allowedMethod method request = return () + | allowedMethod method request = pure () | otherwise = delayedFail err405 -- This has switched between using 'Fail' and 'FailFatal' a number of @@ -366,7 +365,7 @@ methodCheck method request -- recoverable. acceptCheck :: AllMime list => Proxy list -> AcceptHeader -> DelayedIO () acceptCheck proxy accH - | canHandleAcceptH proxy accH = return () + | canHandleAcceptH proxy accH = pure () | otherwise = delayedFail err406 methodRouter @@ -422,7 +421,7 @@ instance => HasServer (Verb method status ctypes a) context where type ServerT (Verb method status ctypes a) m = m a - hoistServerWithContext _ _ nt s = nt s + hoistServerWithContext _ _ nt = nt route Proxy _ = methodRouter ([],) method (Proxy :: Proxy ctypes) status where @@ -439,7 +438,7 @@ instance => HasServer (Verb method status ctypes (Headers h a)) context where type ServerT (Verb method status ctypes (Headers h a)) m = m (Headers h a) - hoistServerWithContext _ _ nt s = nt s + hoistServerWithContext _ _ nt = nt route Proxy _ = methodRouter (\x -> (getHeaders x, getResponse x)) method (Proxy :: Proxy ctypes) status where @@ -451,7 +450,7 @@ instance => HasServer (NoContentVerb method) context where type ServerT (NoContentVerb method) m = m NoContent - hoistServerWithContext _ _ nt s = nt s + hoistServerWithContext _ _ nt = nt route Proxy _ = noContentRouter method status204 where @@ -468,7 +467,7 @@ instance => HasServer (Stream method status framing ctype a) context where type ServerT (Stream method status framing ctype a) m = m a - hoistServerWithContext _ _ nt s = nt s + hoistServerWithContext _ _ nt = nt route Proxy _ = streamRouter ([],) method status (Proxy :: Proxy framing) (Proxy :: Proxy ctype) where @@ -487,7 +486,7 @@ instance => HasServer (Stream method status framing ctype (Headers h a)) context where type ServerT (Stream method status framing ctype (Headers h a)) m = m (Headers h a) - hoistServerWithContext _ _ nt s = nt s + hoistServerWithContext _ _ nt = nt route Proxy _ = streamRouter (\x -> (getHeaders x, getResponse x)) method status (Proxy :: Proxy framing) (Proxy :: Proxy ctype) where @@ -585,7 +584,7 @@ instance unfoldRequestArgument (Proxy :: Proxy mods) errReq errSt mev where mev :: Maybe (Either T.Text a) - mev = fmap parseHeader $ lookup headerName (requestHeaders req) + mev = parseHeader <$> lookup headerName (requestHeaders req) errReq = delayedFailFatal $ @@ -744,7 +743,7 @@ instance paramname = T.pack $ symbolVal (Proxy :: Proxy sym) paramsCheck req = case partitionEithers $ fmap parseQueryParam params of - ([], parsed) -> return parsed + ([], parsed) -> pure parsed (errs, _) -> delayedFailFatal $ formatError rep req $ @@ -894,16 +893,16 @@ instance <> paramname <> T.pack " failed: " <> T.pack e - Right parsed -> return parsed + Right parsed -> pure parsed parseDeepParam :: (T.Text, Maybe T.Text) -> Either String ([T.Text], Maybe T.Text) parseDeepParam (paramname, value) = - let parseParam "" = return [] + let parseParam "" = pure [] parseParam n = reverse <$> go [] n go parsed remaining = case T.take 1 remaining of "[" -> case T.breakOn "]" remaining of (_, "") -> Left $ "Error parsing deep param, missing closing ']': " <> T.unpack remaining - (name, "]") -> return $ T.drop 1 name : parsed + (name, "]") -> pure $ T.drop 1 name : parsed (name, remaining') -> case T.take 2 remaining' of "][" -> go (T.drop 1 name : parsed) (T.drop 1 remaining') _ -> Left $ "Error parsing deep param, incorrect brackets: " <> T.unpack remaining @@ -963,7 +962,7 @@ instance HasServer RawM context where Fail e -> respond' $ Fail e FailFatal e -> respond' $ FailFatal e - hoistServerWithContext _ _ f srvM = \req respond -> f (srvM req respond) + hoistServerWithContext _ _ f srvM req respond = f (srvM req respond) -- | If you use 'ReqBody' in one of the endpoints for your API, -- this automatically requires your server-side handler to be a function @@ -1026,7 +1025,7 @@ instance _ -> Nothing in case canHandleContentTypeH <|> noOptionalReqBody of Nothing -> delayedFail err415 - Just f -> return f + Just f -> pure f bodyCheck f = withRequest $ \request -> let @@ -1037,15 +1036,21 @@ instance serverErr :: String -> ServerError serverErr = formatError rep request + + required = sbool :: SBool (FoldRequired mods) + lenient = sbool :: SBool (FoldLenient mods) in - fmap f (liftIO $ lazyRequestBody request) - >>= case (sbool :: SBool (FoldRequired mods), sbool :: SBool (FoldLenient mods), hasReqBody) of - (STrue, STrue, _) -> return . first T.pack - (STrue, SFalse, _) -> either (delayedFailFatal . serverErr) return - (SFalse, STrue, False) -> return . either (const Nothing) (Just . Right) - (SFalse, SFalse, False) -> return . either (const Nothing) Just - (SFalse, STrue, True) -> return . Just . first T.pack - (SFalse, SFalse, True) -> either (delayedFailFatal . serverErr) (return . Just) + ( liftIO (lazyRequestBody request) + >>= ( case (required, lenient, hasReqBody) of + (STrue, STrue, _) -> pure . first T.pack + (STrue, SFalse, _) -> either (delayedFailFatal . serverErr) pure + (SFalse, STrue, False) -> pure . either (const Nothing) (Just . Right) + (SFalse, SFalse, False) -> pure . either (const Nothing) Just + (SFalse, STrue, True) -> pure . Just . first T.pack + (SFalse, SFalse, True) -> either (delayedFailFatal . serverErr) (pure . Just) + ) + . f + ) instance ( FramingUnrender framing @@ -1065,7 +1070,7 @@ instance where ctCheck :: DelayedIO (SourceIO chunk -> IO a) -- TODO: do content-type check - ctCheck = return fromSourceIO + ctCheck = pure fromSourceIO bodyCheck :: (SourceIO chunk -> IO a) -> DelayedIO a bodyCheck fromRS = withRequest $ \req -> do @@ -1086,7 +1091,7 @@ instance (HasServer api context, KnownSymbol path) => HasServer (path :> api) co (route (Proxy :: Proxy api) context subserver) where proxyPath = Proxy :: Proxy path - hoistServerWithContext _ pc nt s = hoistServerWithContext (Proxy :: Proxy api) pc nt s + hoistServerWithContext _ = hoistServerWithContext (Proxy :: Proxy api) instance HasServer api context => HasServer (RemoteHost :> api) context where type ServerT (RemoteHost :> api) m = SockAddr -> ServerT api m @@ -1124,14 +1129,14 @@ instance HasServer api ctx => HasServer (Summary desc :> api) ctx where type ServerT (Summary desc :> api) m = ServerT api m route _ = route (Proxy :: Proxy api) - hoistServerWithContext _ pc nt s = hoistServerWithContext (Proxy :: Proxy api) pc nt s + hoistServerWithContext _ = hoistServerWithContext (Proxy :: Proxy api) -- | Ignore @'Description'@ in server handlers. instance HasServer api ctx => HasServer (Description desc :> api) ctx where type ServerT (Description desc :> api) m = ServerT api m route _ = route (Proxy :: Proxy api) - hoistServerWithContext _ pc nt s = hoistServerWithContext (Proxy :: Proxy api) pc nt s + hoistServerWithContext _ = hoistServerWithContext (Proxy :: Proxy api) -- | Singleton type representing a server that serves an empty API. data EmptyServer = EmptyServer deriving (Bounded, Enum, Eq, Show, Typeable) @@ -1181,11 +1186,8 @@ instance -- * helpers -ct_wildcard :: B.ByteString -ct_wildcard = "*" <> "/" <> "*" - getAcceptHeader :: Request -> AcceptHeader -getAcceptHeader = AcceptHeader . fromMaybe ct_wildcard . lookup hAccept . requestHeaders +getAcceptHeader = AcceptHeader . fromMaybe "*/*" . lookup hAccept . requestHeaders -- * General Authentication @@ -1199,8 +1201,7 @@ instance ServerT (WithNamedContext name subContext subApi) m = ServerT subApi m - route Proxy context delayed = - route subProxy subContext delayed + route Proxy context = route subProxy subContext where subProxy :: Proxy subApi subProxy = Proxy @@ -1208,7 +1209,7 @@ instance subContext :: Context subContext subContext = descendIntoNamedContext (Proxy :: Proxy name) context - hoistServerWithContext _ _ nt s = hoistServerWithContext (Proxy :: Proxy subApi) (Proxy :: Proxy subContext) nt s + hoistServerWithContext _ _ = hoistServerWithContext (Proxy :: Proxy subApi) (Proxy :: Proxy subContext) ------------------------------------------------------------------------------- -- Custom type errors diff --git a/servant-server/src/Servant/Server/Internal/BasicAuth.hs b/servant-server/src/Servant/Server/Internal/BasicAuth.hs index f9f2a8649..8c2302f41 100644 --- a/servant-server/src/Servant/Server/Internal/BasicAuth.hs +++ b/servant-server/src/Servant/Server/Internal/BasicAuth.hs @@ -54,7 +54,7 @@ decodeBAHdr req = do let decoded = decodeLenient (BS.dropWhile isSpace rest) let (username, passWithColonAtHead) = BS.break (== _colon) decoded (_, password) <- BS.uncons passWithColonAtHead - return (BasicAuthData username password) + pure (BasicAuthData username password) -- | Run and check basic authentication, returning the appropriate http error per -- the spec. @@ -63,10 +63,10 @@ runBasicAuth req realm (BasicAuthCheck ba) = case decodeBAHdr req of Nothing -> plzAuthenticate Just e -> - liftIO (ba e) >>= \res -> case res of + liftIO (ba e) >>= \case BadPassword -> plzAuthenticate NoSuchUser -> plzAuthenticate Unauthorized -> delayedFailFatal err403 - Authorized usr -> return usr + Authorized usr -> pure usr where plzAuthenticate = delayedFailFatal err401{errHeaders = [mkBAChallengerHdr realm]} diff --git a/servant-server/src/Servant/Server/Internal/Delayed.hs b/servant-server/src/Servant/Server/Internal/Delayed.hs index 22dbb4552..bf3036353 100644 --- a/servant-server/src/Servant/Server/Internal/Delayed.hs +++ b/servant-server/src/Servant/Server/Internal/Delayed.hs @@ -4,7 +4,6 @@ {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE TypeFamilies #-} -{-# LANGUAGE TypeOperators #-} {-# LANGUAGE UndecidableInstances #-} module Servant.Server.Internal.Delayed where @@ -120,7 +119,7 @@ emptyDelayed :: RouteResult a -> Delayed env a emptyDelayed result = Delayed (const r) r r r r r r (const r) (\_ _ _ _ _ _ -> result) where - r = return () + r = pure () -- | Add a capture to the end of the capture block. addCapture @@ -280,13 +279,13 @@ runAction action env req respond k = runResourceT $ runDelayed action env req >>= go >>= liftIO . respond where - go (Fail e) = return $ Fail e - go (FailFatal e) = return $ FailFatal e + go (Fail e) = pure $ Fail e + go (FailFatal e) = pure $ FailFatal e go (Route a) = liftIO $ do e <- runHandler a case e of - Left err -> return . Route $ responseServerError err - Right x -> return $! k x + Left err -> pure . Route $ responseServerError err + Right x -> pure $! k x {- Note [Existential Record Update] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/servant-server/src/Servant/Server/Internal/DelayedIO.hs b/servant-server/src/Servant/Server/Internal/DelayedIO.hs index 933194909..c22e7e9d4 100644 --- a/servant-server/src/Servant/Server/Internal/DelayedIO.hs +++ b/servant-server/src/Servant/Server/Internal/DelayedIO.hs @@ -40,7 +40,7 @@ instance MonadBase IO DelayedIO where liftBase = liftIO liftRouteResult :: RouteResult a -> DelayedIO a -liftRouteResult x = DelayedIO $ lift . lift $ RouteResultT . return $ x +liftRouteResult x = DelayedIO $ lift . lift $ RouteResultT . pure $ x instance MonadBaseControl IO DelayedIO where -- type StM DelayedIO a = StM (ReaderT Request (ResourceT (RouteResultT IO))) a diff --git a/servant-server/src/Servant/Server/Internal/RouteResult.hs b/servant-server/src/Servant/Server/Internal/RouteResult.hs index cbf55a394..86f5594c5 100644 --- a/servant-server/src/Servant/Server/Internal/RouteResult.hs +++ b/servant-server/src/Servant/Server/Internal/RouteResult.hs @@ -6,7 +6,7 @@ module Servant.Server.Internal.RouteResult where -import Control.Monad (ap, liftM) +import Control.Monad (ap) import Control.Monad.Base (MonadBase (..)) import Control.Monad.Catch (MonadThrow (..)) import Control.Monad.Trans (MonadIO (..), MonadTrans (..)) @@ -35,7 +35,6 @@ instance Applicative RouteResult where (<*>) = ap instance Monad RouteResult where - return = pure Route a >>= f = f a Fail e >>= _ = Fail e FailFatal e >>= _ = FailFatal e @@ -47,16 +46,15 @@ instance MonadTrans RouteResultT where lift = RouteResultT . fmap Route instance (Functor m, Monad m) => Applicative (RouteResultT m) where - pure = RouteResultT . return . Route + pure = RouteResultT . pure . Route (<*>) = ap instance Monad m => Monad (RouteResultT m) where - return = pure m >>= k = RouteResultT $ do a <- runRouteResultT m case a of - Fail e -> return $ Fail e - FailFatal e -> return $ FailFatal e + Fail e -> pure $ Fail e + FailFatal e -> pure $ FailFatal e Route b -> runRouteResultT (k b) instance MonadIO m => MonadIO (RouteResultT m) where @@ -72,7 +70,7 @@ instance MonadBaseControl b m => MonadBaseControl b (RouteResultT m) where instance MonadTransControl RouteResultT where type StT RouteResultT a = RouteResult a - liftWith f = RouteResultT $ liftM return $ f runRouteResultT + liftWith f = RouteResultT (pure <$> f runRouteResultT) restoreT = RouteResultT instance MonadThrow m => MonadThrow (RouteResultT m) where diff --git a/servant-server/src/Servant/Server/Internal/Router.hs b/servant-server/src/Servant/Server/Internal/Router.hs index e352f55e7..1e297e162 100644 --- a/servant-server/src/Servant/Server/Internal/Router.hs +++ b/servant-server/src/Servant/Server/Internal/Router.hs @@ -142,7 +142,7 @@ sameStructure router1 router2 = -- structure of a router. routerLayout :: Router' env a -> Text routerLayout router = - T.unlines (["/"] ++ mkRouterLayout False (routerStructure router)) + T.unlines ("/" : mkRouterLayout False (routerStructure router)) where mkRouterLayout :: Bool -> RouterStructure -> [Text] mkRouterLayout c (StaticRouterStructure m n) = mkSubTrees c (M.toList m) n @@ -172,7 +172,7 @@ routerLayout router = -- | Apply a transformation to the response of a `Router`. tweakResponse :: (RouteResult Response -> RouteResult Response) -> Router env -> Router env -tweakResponse f = fmap (\a -> \req cont -> a req (cont . f)) +tweakResponse f = fmap (\a req cont -> a req (cont . f)) -- | Interpret a router as an application. runRouter :: NotFoundErrorFormatter -> Router () -> RoutingApplication diff --git a/servant-server/src/Servant/Server/UVerb.hs b/servant-server/src/Servant/Server/UVerb.hs index d497611de..0a3c59a22 100644 --- a/servant-server/src/Servant/Server/UVerb.hs +++ b/servant-server/src/Servant/Server/UVerb.hs @@ -82,7 +82,7 @@ instance AllCTRender cts a => IsServerResource cts a where - resourceResponse request p res = handleAcceptH p (getAcceptHeader request) res + resourceResponse request p = handleAcceptH p (getAcceptHeader request) resourceHeaders _ _ = [] instance @@ -130,7 +130,7 @@ instance where type ServerT (UVerb method contentTypes as) m = m (Union as) - hoistServerWithContext _ _ nt s = nt s + hoistServerWithContext _ _ nt = nt route :: forall env diff --git a/servant-server/test/Servant/ArbitraryMonadServerSpec.hs b/servant-server/test/Servant/ArbitraryMonadServerSpec.hs index 10eae5ce5..9047a86e6 100644 --- a/servant-server/test/Servant/ArbitraryMonadServerSpec.hs +++ b/servant-server/test/Servant/ArbitraryMonadServerSpec.hs @@ -35,27 +35,27 @@ combinedAPI :: Proxy CombinedAPI combinedAPI = Proxy readerServer' :: ServerT ReaderAPI (Reader String) -readerServer' = return 1797 :<|> ask +readerServer' = pure 1797 :<|> ask fReader :: Reader String a -> Handler a -fReader x = return (runReader x "hi") +fReader x = pure (runReader x "hi") readerServer :: Server ReaderAPI readerServer = hoistServer readerAPI fReader readerServer' combinedReaderServer' :: ServerT CombinedAPI (Reader String) -combinedReaderServer' = readerServer' :<|> hoistServer identityAPI (return . runIdentity) (return True) +combinedReaderServer' = readerServer' :<|> hoistServer identityAPI (pure . runIdentity) (pure True) combinedReaderServer :: Server CombinedAPI combinedReaderServer = hoistServer combinedAPI fReader combinedReaderServer' enterSpec :: Spec enterSpec = describe "Enter" $ do - with (return (serve readerAPI readerServer)) $ do + with (pure (serve readerAPI readerServer)) $ do it "allows running arbitrary monads" $ do get "int" `shouldRespondWith` "1797" post "string" "3" `shouldRespondWith` "\"hi\""{matchStatus = 200} - with (return (serve combinedAPI combinedReaderServer)) $ do + with (pure (serve combinedAPI combinedReaderServer)) $ do it "allows combnation of enters" $ do get "bool" `shouldRespondWith` "true" diff --git a/servant-server/test/Servant/HoistSpec.hs b/servant-server/test/Servant/HoistSpec.hs index de84bec38..8eaffebc5 100644 --- a/servant-server/test/Servant/HoistSpec.hs +++ b/servant-server/test/Servant/HoistSpec.hs @@ -37,4 +37,4 @@ server' = hoistServer api f server ------------------------------------------------------------------------------- spec :: Spec -spec = return () +spec = pure () diff --git a/servant-server/test/Servant/Server/ErrorSpec.hs b/servant-server/test/Servant/Server/ErrorSpec.hs index 1f6397349..11d34781f 100644 --- a/servant-server/test/Servant/Server/ErrorSpec.hs +++ b/servant-server/test/Servant/Server/ErrorSpec.hs @@ -41,8 +41,8 @@ errorOrderAuthCheck :: BasicAuthCheck () errorOrderAuthCheck = let check (BasicAuthData username password) = if username == "servant" && password == "server" - then return (Authorized ()) - else return Unauthorized + then pure (Authorized ()) + else pure Unauthorized in BasicAuthCheck check ------------------------------------------------------------------------------ @@ -61,7 +61,7 @@ errorOrderApi :: Proxy ErrorOrderApi errorOrderApi = Proxy errorOrderServer :: Server ErrorOrderApi -errorOrderServer = \_ _ _ _ -> throwError err402 +errorOrderServer _ _ _ _ = throwError err402 -- On error priorities: -- @@ -84,7 +84,7 @@ errorOrderSpec :: Spec errorOrderSpec = describe "HTTP error order" $ with - ( return $ + ( pure $ serveWithContext errorOrderApi (errorOrderAuthCheck :. EmptyContext) @@ -131,8 +131,8 @@ errorOrderSpec = badBodyRes <- request goodMethod goodUrl [goodAuth, goodContentType, goodAccept] badBody -- Both bad body and bad params result in 400 - return badParamsRes `shouldRespondWith` 400 - return badBodyRes `shouldRespondWith` 400 + pure badParamsRes `shouldRespondWith` 400 + pure badBodyRes `shouldRespondWith` 400 -- Param check should occur before body checks both <- request goodMethod badParams [goodAuth, goodContentType, goodAccept] badBody @@ -159,8 +159,8 @@ prioErrorsApi = Proxy -- request body unless the path actually matches. prioErrorsSpec :: Spec prioErrorsSpec = describe "PrioErrors" $ do - let server = return - with (return $ serve prioErrorsApi server) $ do + let server = pure + with (pure $ serve prioErrorsApi server) $ do let check (mdescr, method) path (cdescr, ctype, body) resp = it fulldescr $ Test.Hspec.Wai.request method path [(hContentType, ctype)] body @@ -228,20 +228,20 @@ errorRetryApi = Proxy errorRetryServer :: Server ErrorRetryApi errorRetryServer = (\_ -> throwError err402) - :<|> (\_ -> return 1) - :<|> (\_ -> return 2) - :<|> (\_ -> return 3) - :<|> (\_ -> return 4) - :<|> (\_ _ -> return 5) - :<|> (\_ -> return 6) - :<|> (\_ -> return 7) - :<|> (\_ -> return 8) + :<|> (\_ -> pure 1) + :<|> (\_ -> pure 2) + :<|> (\_ -> pure 3) + :<|> (\_ -> pure 4) + :<|> (\_ _ -> pure 5) + :<|> (\_ -> pure 6) + :<|> (\_ -> pure 7) + :<|> (\_ -> pure 8) errorRetrySpec :: Spec errorRetrySpec = describe "Handler search" $ with - ( return $ + ( pure $ serveWithContext errorRetryApi (errorOrderAuthCheck :. EmptyContext) @@ -289,16 +289,16 @@ errorChoiceApi = Proxy errorChoiceServer :: Server ErrorChoiceApi errorChoiceServer = - return 0 - :<|> return 1 - :<|> return 2 - :<|> (\_ -> return 3) - :<|> ((\_ -> return 4) :<|> (\_ -> return 5)) - :<|> ((\_ -> return 6) :<|> (\_ -> return 7)) + pure 0 + :<|> pure 1 + :<|> pure 2 + :<|> (\_ -> pure 3) + :<|> ((\_ -> pure 4) :<|> (\_ -> pure 5)) + :<|> ((\_ -> pure 6) :<|> (\_ -> pure 7)) errorChoiceSpec :: Spec errorChoiceSpec = describe "Multiple handlers return errors" $ - with (return $ serve errorChoiceApi errorChoiceServer) $ do + with (pure $ serve errorChoiceApi errorChoiceServer) $ do it "should respond with 404 if no path matches" $ do request methodGet "" [] "" `shouldRespondWith` 404 @@ -352,13 +352,13 @@ customFormatterAPI = Proxy customFormatterServer :: Server CustomFormatterAPI customFormatterServer = - (\_ -> return "query") - :<|> (\_ -> return "capture") - :<|> (\_ -> return "body") + (\_ -> pure "query") + :<|> (\_ -> pure "capture") + :<|> (\_ -> pure "body") customFormattersSpec :: Spec customFormattersSpec = describe "Custom errors from combinators" $ - with (return $ serveWithContext customFormatterAPI (customFormatters :. EmptyContext) customFormatterServer) $ do + with (pure $ serveWithContext customFormatterAPI (customFormatters :. EmptyContext) customFormatterServer) $ do let startsWithCustom = ResponseMatcher { matchStatus = 400 diff --git a/servant-server/test/Servant/Server/Internal/RoutingApplicationSpec.hs b/servant-server/test/Servant/Server/Internal/RoutingApplicationSpec.hs index a4cda9b1a..f132d0c60 100644 --- a/servant-server/test/Servant/Server/Internal/RoutingApplicationSpec.hs +++ b/servant-server/test/Servant/Server/Internal/RoutingApplicationSpec.hs @@ -1,6 +1,5 @@ {-# LANGUAGE DataKinds #-} {-# LANGUAGE FlexibleInstances #-} -{-# LANGUAGE KindSignatures #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE ScopedTypeVariables #-} @@ -35,6 +34,7 @@ data TestResource x -- Let's not write to the filesystem delayedTestRef :: IORef (TestResource String) +{-# NOINLINE delayedTestRef #-} delayedTestRef = unsafePerformIO $ newIORef TestResourceNone fromTestResource :: a -> (b -> a) -> TestResource b -> a @@ -45,25 +45,25 @@ initTestResource :: IO () initTestResource = writeIORef delayedTestRef TestResourceNone writeTestResource :: String -> IO () -writeTestResource x = modifyIORef delayedTestRef $ \r -> case r of +writeTestResource x = modifyIORef delayedTestRef $ \case TestResourceNone -> TestResource x _ -> TestResourceError freeTestResource :: IO () -freeTestResource = modifyIORef delayedTestRef $ \r -> case r of +freeTestResource = modifyIORef delayedTestRef $ \case TestResource _ -> TestResourceFreed _ -> TestResourceError delayed :: DelayedIO () -> RouteResult (Handler ()) -> Delayed () (Handler ()) delayed body srv = Delayed - { capturesD = \() -> return () - , methodD = return () - , authD = return () - , acceptD = return () - , contentD = return () - , paramsD = return () - , headersD = return () + { capturesD = \() -> pure () + , methodD = pure () + , authD = pure () + , acceptD = pure () + , contentD = pure () + , paramsD = pure () + , headersD = pure () , bodyD = \() -> do liftIO (writeTestResource "hia" >> putStrLn "garbage created") _ <- register (freeTestResource >> putStrLn "garbage collected") @@ -76,7 +76,7 @@ simpleRun -> IO () simpleRun d = fmap (either ignoreE id) . try $ - runAction d () defaultRequest (\_ -> return ()) (\_ -> FailFatal err500) + runAction d () defaultRequest (\_ -> pure ()) (\_ -> FailFatal err500) where ignoreE :: SomeException -> () ignoreE = const () @@ -95,13 +95,13 @@ instance (HasServer api ctx, KnownSymbol sym) => HasServer (Res sym :> api) ctx route Proxy ctx server = route (Proxy :: Proxy api) ctx $ - addBodyCheck server (return ()) check + addBodyCheck server (pure ()) check where sym = symbolVal (Proxy :: Proxy sym) check () = do liftIO $ writeTestResource sym _ <- register freeTestResource - return delayedTestRef + pure delayedTestRef type ResApi = "foobar" :> Res "foobar" :> Get '[PlainText] T.Text @@ -109,7 +109,7 @@ resApi :: Proxy ResApi resApi = Proxy resServer :: Server ResApi -resServer ref = liftIO $ fmap (fromTestResource "" T.pack) $ readIORef ref +resServer ref = liftIO (fromTestResource "" T.pack <$> readIORef ref) ------------------------------------------------------------------------------- -- Spec @@ -120,26 +120,26 @@ spec = do describe "Delayed" $ do it "actually runs clean up actions" $ do liftIO initTestResource - _ <- simpleRun $ delayed (return ()) (Route $ return ()) + _ <- simpleRun $ delayed (pure ()) (Route $ pure ()) res <- readIORef delayedTestRef res `shouldBe` TestResourceFreed it "even with exceptions in serverD" $ do liftIO initTestResource - _ <- simpleRun $ delayed (return ()) (Route $ throw DivideByZero) + _ <- simpleRun $ delayed (pure ()) (Route $ throw DivideByZero) res <- readIORef delayedTestRef res `shouldBe` TestResourceFreed it "even with routing failure in bodyD" $ do liftIO initTestResource - _ <- simpleRun $ delayed (delayedFailFatal err500) (Route $ return ()) + _ <- simpleRun $ delayed (delayedFailFatal err500) (Route $ pure ()) res <- readIORef delayedTestRef res `shouldBe` TestResourceFreed it "even with exceptions in bodyD" $ do liftIO initTestResource - _ <- simpleRun $ delayed (liftIO $ throwIO DivideByZero) (Route $ return ()) + _ <- simpleRun $ delayed (liftIO $ throwIO DivideByZero) (Route $ pure ()) res <- readIORef delayedTestRef res `shouldBe` TestResourceFreed describe "ResApi" $ - with (return $ serve resApi resServer) $ do + with (pure $ serve resApi resServer) $ do it "writes and cleanups resources" $ do liftIO initTestResource request "GET" "foobar" [] "" `shouldRespondWith` "foobar" diff --git a/servant-server/test/Servant/Server/RouterSpec.hs b/servant-server/test/Servant/Server/RouterSpec.hs index 066bad68c..c2004243c 100644 --- a/servant-server/test/Servant/Server/RouterSpec.hs +++ b/servant-server/test/Servant/Server/RouterSpec.hs @@ -39,7 +39,7 @@ routerSpec = do twk (ResponseBuilder (Status i s) hs b) = ResponseBuilder (Status (i + 1) s) hs b twk b = b - with (return app') $ do + with (pure app') $ do it "calls f on route result" $ do get "" `shouldRespondWith` 202 diff --git a/servant-server/test/Servant/Server/StaticFilesSpec.hs b/servant-server/test/Servant/Server/StaticFilesSpec.hs index 36f7517ed..2fdf6fb76 100644 --- a/servant-server/test/Servant/Server/StaticFilesSpec.hs +++ b/servant-server/test/Servant/Server/StaticFilesSpec.hs @@ -35,7 +35,7 @@ app = serve api server server :: Server Api server = - (\name_ -> return (Person name_ 42)) + (\name_ -> pure (Person name_ 42)) :<|> serveDirectoryFileServer "static" withStaticFiles :: IO () -> IO () @@ -48,14 +48,14 @@ withStaticFiles action = withSystemTempDirectory "servant-test" $ \tmpDir -> createDirectory "static" writeFile "static/foo.txt" "bar" writeFile "static/index.html" "index" - return outer + pure outer teardown outer = do setCurrentDirectory outer spec :: Spec spec = do - around_ withStaticFiles $ with (return app) $ do + around_ withStaticFiles $ with (pure app) $ do describe "serveDirectory" $ do it "successfully serves files" $ do get "/static/foo.txt" `shouldRespondWith` "bar" diff --git a/servant-server/test/Servant/Server/StreamingSpec.hs b/servant-server/test/Servant/Server/StreamingSpec.hs index 6109fd4fc..b544f09e8 100644 --- a/servant-server/test/Servant/Server/StreamingSpec.hs +++ b/servant-server/test/Servant/Server/StreamingSpec.hs @@ -52,12 +52,12 @@ spec = do streamTestData <- do mvar :: MVar [IO Strict.ByteString] <- newMVar $ - map return (replicate 1000 "foo") - ++ (waitFor serverReceivedFirstChunk >> return "foo") - : map return (replicate 1000 "foo") - return $ modifyMVar mvar $ \actions -> case actions of + replicate 1000 (pure "foo") + ++ (waitFor serverReceivedFirstChunk >> pure "foo") + : replicate 1000 (pure "foo") + pure $ modifyMVar mvar $ \case (a : r) -> (r,) <$> a - [] -> return ([], "") + [] -> pure ([], "") let request = defaultRequest @@ -74,7 +74,7 @@ spec = do prefix `shouldBe` "foo" notify serverReceivedFirstChunk () input `shouldBe` mconcat (replicate 2001 "foo") - return NoContent + pure NoContent app = serve testAPI handler response <- executeRequest app request @@ -85,14 +85,14 @@ executeRequest app request = do responseMVar <- newEmptyMVar let respondToRequest response = do putMVar responseMVar response - return ResponseReceived + pure ResponseReceived ResponseReceived <- app request respondToRequest takeMVar responseMVar timeout :: IO a -> IO a timeout action = do result <- System.Timeout.timeout 1000000 action - maybe (throwIO $ ErrorCall "timeout") return result + maybe (throwIO $ ErrorCall "timeout") pure result -- * waiter @@ -105,7 +105,7 @@ data Waiter a newWaiter :: IO (Waiter a) newWaiter = do mvar <- newEmptyMVar - return $ + pure $ Waiter { notify = putMVar mvar , waitFor = readMVar mvar diff --git a/servant-server/test/Servant/Server/UsingContextSpec.hs b/servant-server/test/Servant/Server/UsingContextSpec.hs index a5e445bca..3f189c7a6 100644 --- a/servant-server/test/Servant/Server/UsingContextSpec.hs +++ b/servant-server/test/Servant/Server/UsingContextSpec.hs @@ -25,7 +25,7 @@ type OneEntryAPI = ExtractFromContext :> Get '[JSON] String testServer :: String -> Handler String -testServer s = return s +testServer = pure oneEntryApp :: Application oneEntryApp = @@ -52,11 +52,11 @@ oneEntryTwiceApp = spec1 :: Spec spec1 = do describe "accessing context entries from custom combinators" $ do - with (return oneEntryApp) $ do + with (pure oneEntryApp) $ do it "allows retrieving a ContextEntry" $ do get "/" `shouldRespondWith` "\"contextEntry\"" - with (return oneEntryTwiceApp) $ do + with (pure oneEntryTwiceApp) $ do it "allows retrieving the same ContextEntry twice" $ do get "/foo" `shouldRespondWith` "\"contextEntryTwice\"" get "/bar" `shouldRespondWith` "\"contextEntryTwice\"" @@ -74,14 +74,14 @@ type InjectAPI = injectApp :: Application injectApp = serveWithContext (Proxy :: Proxy InjectAPI) context $ - (\s -> return s) - :<|> (\s -> return ("tagged: " ++ s)) + pure + :<|> (\s -> pure ("tagged: " ++ s)) where context = EmptyContext spec2 :: Spec spec2 = do - with (return injectApp) $ do + with (pure injectApp) $ do describe "inserting context entries with custom combinators" $ do it "allows to inject context entries" $ do get "/untagged" `shouldRespondWith` "\"injected\"" @@ -102,15 +102,15 @@ withBirdfaceApp = testServer :<|> testServer where - context :: Context '[String, (NamedContext "sub" '[String])] + context :: Context '[String, NamedContext "sub" '[String]] context = "firstEntry" - :. (NamedContext ("secondEntry" :. EmptyContext)) + :. NamedContext ("secondEntry" :. EmptyContext) :. EmptyContext spec3 :: Spec spec3 = do - with (return withBirdfaceApp) $ do + with (pure withBirdfaceApp) $ do it "allows retrieving different ContextEntries for the same combinator" $ do get "/foo" `shouldRespondWith` "\"firstEntry\"" get "/bar" `shouldRespondWith` "\"secondEntry\"" @@ -122,14 +122,14 @@ type NamedContextAPI = (ExtractFromContext :> Get '[JSON] String) namedContextApp :: Application -namedContextApp = serveWithContext (Proxy :: Proxy NamedContextAPI) context return +namedContextApp = serveWithContext (Proxy :: Proxy NamedContextAPI) context pure where context :: Context '[NamedContext "sub" '[String]] context = NamedContext ("descend" :. EmptyContext) :. EmptyContext spec4 :: Spec spec4 = do - with (return namedContextApp) $ do + with (pure namedContextApp) $ do describe "WithNamedContext" $ do it "allows descending into a subcontext for a given api" $ do get "/" `shouldRespondWith` "\"descend\"" diff --git a/servant-server/test/Servant/Server/UsingContextSpec/TestCombinators.hs b/servant-server/test/Servant/Server/UsingContextSpec/TestCombinators.hs index 3477a6c48..db11595cd 100644 --- a/servant-server/test/Servant/Server/UsingContextSpec/TestCombinators.hs +++ b/servant-server/test/Servant/Server/UsingContextSpec/TestCombinators.hs @@ -1,7 +1,6 @@ {-# LANGUAGE DataKinds #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} -{-# LANGUAGE KindSignatures #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE PolyKinds #-} {-# LANGUAGE ScopedTypeVariables #-} @@ -52,11 +51,9 @@ instance ServerT (InjectIntoContext :> subApi) m = ServerT subApi m - hoistServerWithContext _ _ nt s = - hoistServerWithContext (Proxy :: Proxy subApi) (Proxy :: Proxy (String ': context)) nt s + hoistServerWithContext _ _ = hoistServerWithContext (Proxy :: Proxy subApi) (Proxy :: Proxy (String ': context)) - route Proxy context delayed = - route subProxy newContext delayed + route Proxy context = route subProxy newContext where subProxy :: Proxy subApi subProxy = Proxy @@ -73,11 +70,9 @@ instance ServerT (NamedContextWithBirdface name subContext :> subApi) m = ServerT subApi m - hoistServerWithContext _ _ nt s = - hoistServerWithContext (Proxy :: Proxy subApi) (Proxy :: Proxy subContext) nt s + hoistServerWithContext _ _ = hoistServerWithContext (Proxy :: Proxy subApi) (Proxy :: Proxy subContext) - route Proxy context delayed = - route subProxy subContext delayed + route Proxy context = route subProxy subContext where subProxy :: Proxy subApi subProxy = Proxy diff --git a/servant-server/test/Servant/ServerSpec.hs b/servant-server/test/Servant/ServerSpec.hs index 9d2d3e095..f3b36bcdc 100644 --- a/servant-server/test/Servant/ServerSpec.hs +++ b/servant-server/test/Servant/ServerSpec.hs @@ -210,13 +210,13 @@ verbSpec :: Spec verbSpec = describe "Servant.API.Verb" $ do let server :: Server (VerbApi method status) server = - return alice - :<|> return NoContent - :<|> return (addHeader 5 alice) - :<|> return (addHeader 10 NoContent) - :<|> return (addHeader' 5 alice) - :<|> (return alice :<|> return "B") - :<|> return (S.source ["bytestring"]) + pure alice + :<|> pure NoContent + :<|> pure (addHeader 5 alice) + :<|> pure (addHeader 10 NoContent) + :<|> pure (addHeader' 5 alice) + :<|> (pure alice :<|> pure "B") + :<|> pure (S.source ["bytestring"]) get200 = Proxy :: Proxy (VerbApi 'GET 200) post210 = Proxy :: Proxy (VerbApi 'POST 210) @@ -225,7 +225,7 @@ verbSpec = describe "Servant.API.Verb" $ do patch214 = Proxy :: Proxy (VerbApi 'PATCH 214) wrongMethod m = if m == methodPatch then methodPost else methodPatch test desc api method (status :: Int) = context desc $ - with (return $ serve api server) $ do + with (pure $ serve api server) $ do -- HEAD and 214/215 need not return bodies unless (status `elem` [214, 215] || method == methodHead) $ it "returns the person" $ do @@ -322,22 +322,22 @@ captureServer = getLegs :<|> getEars :<|> getEyes where getLegs :: Integer -> Handler Animal getLegs legs = case legs of - 4 -> return jerry - 2 -> return tweety + 4 -> pure jerry + 2 -> pure tweety _ -> throwError err404 getEars :: Either String Integer -> Handler Animal - getEars (Left _) = return chimera -- ignore integer parse error, return weird animal - getEars (Right 2) = return jerry + getEars (Left _) = pure chimera -- ignore integer parse error, return weird animal + getEars (Right 2) = pure jerry getEars (Right _) = throwError err404 getEyes :: Integer -> Handler Animal - getEyes 2 = return jerry + getEyes 2 = pure jerry getEyes _ = throwError err404 captureSpec :: Spec captureSpec = describe "Servant.API.Capture" $ do - with (return (serve captureApi captureServer)) $ do + with (pure (serve captureApi captureServer)) $ do it "can capture parts of the 'pathInfo'" $ do response <- get "/2" liftIO $ decode' (simpleBody response) `shouldBe` Just tweety @@ -355,7 +355,7 @@ captureSpec = describe "Servant.API.Capture" $ do it "returns 400 if parsing integer fails on Strict Capture" $ get "/eyes/bla" `shouldRespondWith` 400 with - ( return + ( pure ( serve (Proxy :: Proxy (Capture "captured" String :> Raw)) ( \"captured" -> Tagged $ \request_ sendResponse -> @@ -364,7 +364,7 @@ captureSpec = describe "Servant.API.Capture" $ do ) ) $ it "strips the captured path snippet from pathInfo" - $ get "/captured/foo" `shouldRespondWith` (fromString (show ["foo" :: String])) + $ get "/captured/foo" `shouldRespondWith` fromString (show ["foo" :: String]) -- }}} ------------------------------------------------------------------------------ @@ -381,12 +381,12 @@ captureAllApi :: Proxy CaptureAllApi captureAllApi = Proxy captureAllServer :: Server CaptureAllApi -captureAllServer = handleLegs :<|> return +captureAllServer = handleLegs :<|> pure where - handleLegs [] = return beholder + handleLegs [] = pure beholder handleLegs legs = case sum legs of - 4 -> return jerry - 2 -> return tweety + 4 -> pure jerry + 2 -> pure tweety _ -> throwError err404 type RootedCaptureAllApi = CaptureAll "xs" String :> Get '[JSON] [String] @@ -396,7 +396,7 @@ captureAllSpec = do let getStringList = decode' @[String] . simpleBody describe "Servant.API.CaptureAll" $ do - with (return (serve captureAllApi captureAllServer)) $ do + with (pure (serve captureAllApi captureAllServer)) $ do it "can capture a single element of the 'pathInfo'" $ do response <- get "/legs/2" liftIO $ decode' (simpleBody response) `shouldBe` Just tweety @@ -431,7 +431,7 @@ captureAllSpec = do response <- get "/arms//" liftIO $ getStringList response `shouldBe` Just [""] - with (return (serve (Proxy :: Proxy RootedCaptureAllApi) return)) $ do + with (pure (serve (Proxy :: Proxy RootedCaptureAllApi) pure)) $ do it "can capture empty rooted capture all" $ do response <- get "/" liftIO $ getStringList response `shouldBe` Just [] @@ -441,7 +441,7 @@ captureAllSpec = do liftIO $ getStringList response `shouldBe` Just [""] with - ( return + ( pure ( serve (Proxy :: Proxy (CaptureAll "segments" String :> Raw)) ( \_captured -> Tagged $ \request_ sendResponse -> @@ -470,7 +470,7 @@ instance FromDeepQuery Filter where let maybeToRight l = maybe (Left l) Right age' <- maybeToRight "missing age" $ readMaybe . T.unpack =<< join (lookup ["age"] params) name' <- maybeToRight "missing name" $ join $ lookup ["name"] params - return $ Filter age' (T.unpack name') + pure $ Filter age' (T.unpack name') type QueryParamApi = QueryParam "name" String :> Get '[JSON] Person @@ -487,33 +487,33 @@ queryParamApi = Proxy qpServer :: Server QueryParamApi qpServer = queryParamServer :<|> qpNames :<|> qpCapitalize :<|> qpAge :<|> qpAges :<|> qpRaw :<|> qpDeep where - qpNames (_ : name2 : _) = return alice{name = name2} - qpNames _ = return alice + qpNames (_ : name2 : _) = pure alice{name = name2} + qpNames _ = pure alice - qpCapitalize False = return alice - qpCapitalize True = return alice{name = map toUpper (name alice)} + qpCapitalize False = pure alice + qpCapitalize True = pure alice{name = map toUpper (name alice)} - qpAge Nothing = return alice - qpAge (Just age') = return alice{age = age'} + qpAge Nothing = pure alice + qpAge (Just age') = pure alice{age = age'} - qpAges ages = return alice{age = sum ages} + qpAges ages = pure alice{age = sum ages} qpRaw q = - return + pure alice { name = maybe mempty BS8.unpack $ join (lookup "name" q) , age = fromMaybe 0 (readMaybe . BS8.unpack =<< join (lookup "age" q)) } qpDeep filter' = - return + pure alice { name = nameFilter filter' , age = ageFilter filter' } - queryParamServer (Just name_) = return alice{name = name_} - queryParamServer Nothing = return alice + queryParamServer (Just name_) = pure alice{name = name_} + queryParamServer Nothing = pure alice queryParamSpec :: Spec queryParamSpec = do @@ -560,7 +560,7 @@ queryParamSpec = do flip runSession (serve queryParamApi qpServer) $ do response <- mkRequest "?age=foo" ["param"] liftIO $ statusCode (simpleStatus response) `shouldBe` 400 - return () + pure () it "parses multiple query parameters" $ flip runSession (serve queryParamApi qpServer) $ do @@ -576,7 +576,7 @@ queryParamSpec = do flip runSession (serve queryParamApi qpServer) $ do response <- mkRequest "?ages=2&ages=foo" ["multiparam"] liftIO $ statusCode (simpleStatus response) `shouldBe` 400 - return () + pure () it "allows retrieving value-less GET parameters" $ flip runSession (serve queryParamApi qpServer) $ do @@ -713,8 +713,8 @@ fragmentApi = Proxy fragServer :: Server FragmentApi fragServer = fragmentServer :<|> fragAge where - fragmentServer = return alice - fragAge = return alice + fragmentServer = pure alice + fragAge = pure alice fragmentSpec :: Spec fragmentSpec = do @@ -747,14 +747,14 @@ reqBodyApi = Proxy reqBodySpec :: Spec reqBodySpec = describe "Servant.API.ReqBody" $ do let server :: Server ReqBodyApi - server = return :<|> return . age :<|> return . maybe 0 age + server = pure :<|> pure . age :<|> pure . maybe 0 age mkReq method x = THW.request method x [(hContentType, "application/json;charset=utf-8")] - with (return $ serve reqBodyApi server) $ do + with (pure $ serve reqBodyApi server) $ do it "passes the argument to the handler" $ do response <- mkReq methodPost "" (encode alice) liftIO $ decode' (simpleBody response) `shouldBe` Just alice @@ -819,28 +819,28 @@ headerSpec = describe "Servant.API.Header" $ do let expectsInt :: Maybe Int -> Handler NoContent expectsInt (Just x) = do when (x /= 5) $ error "Expected 5" - return NoContent + pure NoContent expectsInt Nothing = error "Expected an int" let expectsString :: Maybe String -> Handler NoContent expectsString (Just x) = do when (x /= "more from you") $ error "Expected more from you" - return NoContent + pure NoContent expectsString Nothing = error "Expected a string" - with (return (serve (headerApi (Proxy :: Proxy Int)) expectsInt)) $ do + with (pure (serve (headerApi (Proxy :: Proxy Int)) expectsInt)) $ do let delete' x = THW.request methodDelete x [("MyHeader", "5")] it "passes the header to the handler (Int)" $ delete' "/" "" `shouldRespondWith` 200 - with (return (serve (headerApi (Proxy :: Proxy String)) expectsString)) $ do + with (pure (serve (headerApi (Proxy :: Proxy String)) expectsString)) $ do let delete' x = THW.request methodDelete x [("MyHeader", "more from you")] it "passes the header to the handler (String)" $ delete' "/" "" `shouldRespondWith` 200 - with (return (serve (headerApi (Proxy :: Proxy Int)) expectsInt)) $ do + with (pure (serve (headerApi (Proxy :: Proxy Int)) expectsInt)) $ do let delete' x = THW.request methodDelete x [("MyHeader", "not a number")] it "checks for parse errors" $ @@ -951,15 +951,15 @@ alternativeApi = Proxy alternativeServer :: Server AlternativeApi alternativeServer = - return alice - :<|> return jerry - :<|> return "a string" - :<|> return jerry - :<|> return jerry - :<|> return NoContent + pure alice + :<|> pure jerry + :<|> pure "a string" + :<|> pure jerry + :<|> pure jerry + :<|> pure NoContent alternativeSpec :: Spec -alternativeSpec = describe "Servant.API.Alternative" $ with (return $ serve alternativeApi alternativeServer) $ do +alternativeSpec = describe "Servant.API.Alternative" $ with (pure $ serve alternativeApi alternativeServer) $ do it "unions endpoints" $ do response <- get "/foo" liftIO $ @@ -988,11 +988,11 @@ type ResponseHeadersApi = responseHeadersServer :: Server ResponseHeadersApi responseHeadersServer = - let h = return $ addHeader 5 $ addHeader "kilroy" "hi" + let h = pure $ addHeader 5 $ addHeader "kilroy" "hi" in h :<|> h :<|> h :<|> h responseHeadersSpec :: Spec -responseHeadersSpec = describe "ResponseHeaders" $ with (return $ serve (Proxy :: Proxy ResponseHeadersApi) responseHeadersServer) $ do +responseHeadersSpec = describe "ResponseHeaders" $ with (pure $ serve (Proxy :: Proxy ResponseHeadersApi) responseHeadersServer) $ do let methods = [methodGet, methodPost, methodPut, methodPatch] it "includes the headers in the response" $ @@ -1034,7 +1034,7 @@ uverbResponseHeadersServer False = respond . WithStatus @404 $ ("bar" :: String) uverbResponseHeadersSpec :: Spec uverbResponseHeadersSpec = describe "UVerbResponseHeaders" $ - with (return $ serve (Proxy :: Proxy UVerbResponseHeadersApi) uverbResponseHeadersServer) $ + with (pure $ serve (Proxy :: Proxy UVerbResponseHeadersApi) uverbResponseHeadersServer) $ it "includes the headers in the response" $ THW.request methodGet "/true" [] "" `shouldRespondWith` "\"foo\"" @@ -1064,13 +1064,13 @@ miscServ = :<|> hostHandler :<|> emptyServer where - versionHandler = return . show - secureHandler Secure = return "secure" - secureHandler NotSecure = return "not secure" - hostHandler = return . show + versionHandler = pure . show + secureHandler Secure = pure "secure" + secureHandler NotSecure = pure "not secure" + hostHandler = pure . show miscCombinatorSpec :: Spec -miscCombinatorSpec = with (return $ serve miscApi miscServ) $ +miscCombinatorSpec = with (pure $ serve miscApi miscServ) $ describe "Misc. combinators for request inspection" $ do it "Successfully gets the HTTP version specified in the request" $ go "/version" "\"HTTP/1.0\"" @@ -1102,19 +1102,19 @@ basicAuthApi = Proxy basicAuthServer :: Server BasicAuthAPI basicAuthServer = - const (return jerry) + const (pure jerry) :<|> Tagged (\_ sendResponse -> sendResponse $ responseLBS imATeapot418 [] "") basicAuthContext :: Context '[BasicAuthCheck ()] basicAuthContext = let basicHandler = BasicAuthCheck $ \(BasicAuthData usr pass) -> if usr == "servant" && pass == "server" - then return (Authorized ()) - else return Unauthorized + then pure (Authorized ()) + else pure Unauthorized in basicHandler :. EmptyContext basicAuthSpec :: Spec -basicAuthSpec = describe "Servant.API.BasicAuth" $ with (return (serveWithContext basicAuthApi basicAuthContext basicAuthServer)) $ context "Basic Authentication" $ do +basicAuthSpec = describe "Servant.API.BasicAuth" $ with (pure (serveWithContext basicAuthApi basicAuthContext basicAuthServer)) $ context "Basic Authentication" $ do let basicAuthHeaders user password = [("Authorization", "Basic " <> Base64.encode (user <> ":" <> password))] it "returns 401 when no credentials given" $ do @@ -1147,21 +1147,21 @@ genAuthApi = Proxy genAuthServer :: Server GenAuthAPI genAuthServer = - const (return tweety) + const (pure tweety) :<|> Tagged (\_ sendResponse -> sendResponse $ responseLBS imATeapot418 [] "") type instance AuthServerData (AuthProtect "auth") = () genAuthContext :: Context '[AuthHandler Request ()] genAuthContext = - let authHandler = \req -> case lookup "Auth" (requestHeaders req) of - Just "secret" -> return () + let authHandler req = case lookup "Auth" (requestHeaders req) of + Just "secret" -> pure () Just _ -> throwError err403 Nothing -> throwError err401 in mkAuthHandler authHandler :. EmptyContext genAuthSpec :: Spec -genAuthSpec = describe "Servant.API.Auth" $ with (return (serveWithContext genAuthApi genAuthContext genAuthServer)) $ context "Custom Auth Protection" $ do +genAuthSpec = describe "Servant.API.Auth" $ with (pure (serveWithContext genAuthApi genAuthContext genAuthServer)) $ context "Custom Auth Protection" $ do it "returns 401 when missing headers" $ do get "/auth" `shouldRespondWith` 401 diff --git a/servant-swagger/example/src/Todo.hs b/servant-swagger/example/src/Todo.hs index 86615a4e9..ab4474c9c 100644 --- a/servant-swagger/example/src/Todo.hs +++ b/servant-swagger/example/src/Todo.hs @@ -74,7 +74,7 @@ todoSwagger = -- | Combined server of a Todo service with Swagger documentation. server :: Server API -server = return todoSwagger :<|> error "not implemented" +server = pure todoSwagger :<|> error "not implemented" -- | Output generated @swagger.json@ file for the @'TodoAPI'@. writeSwaggerJSON :: IO () diff --git a/servant-swagger/src/Servant/Swagger/Internal.hs b/servant-swagger/src/Servant/Swagger/Internal.hs index 668d55735..aa3a842ad 100644 --- a/servant-swagger/src/Servant/Swagger/Internal.hs +++ b/servant-swagger/src/Servant/Swagger/Internal.hs @@ -118,8 +118,7 @@ mkEndpointNoContent -> proxy (Verb method status cs (Headers hs nocontent)) -- ^ Method, content-types, headers and response. -> Swagger -mkEndpointNoContent path proxy = - mkEndpointWithSchemaRef Nothing path proxy +mkEndpointNoContent = mkEndpointWithSchemaRef Nothing -- | Like @'mkEndpoint'@ but with explicit schema reference. -- Unlike @'mkEndpoint'@ this function does not update @'definitions'@. @@ -189,7 +188,7 @@ markdownCode :: Text -> Text markdownCode s = "`" <> s <> "`" addDefaultResponse400 :: ParamName -> Swagger -> Swagger -addDefaultResponse400 pname = setResponseWith (\old _new -> alter400 old) 400 (return response400) +addDefaultResponse400 pname = setResponseWith (\old _new -> alter400 old) 400 (pure response400) where sname = markdownCode pname description400 = "Invalid " <> sname diff --git a/servant-swagger/src/Servant/Swagger/Internal/Orphans.hs b/servant-swagger/src/Servant/Swagger/Internal/Orphans.hs index aba82f926..8c9700e17 100644 --- a/servant-swagger/src/Servant/Swagger/Internal/Orphans.hs +++ b/servant-swagger/src/Servant/Swagger/Internal/Orphans.hs @@ -1,4 +1,3 @@ -{-# LANGUAGE CPP #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE StandaloneDeriving #-} @@ -8,10 +7,8 @@ module Servant.Swagger.Internal.Orphans where import Data.Proxy (Proxy (..)) import Data.Swagger -import Servant.Types.SourceT (SourceT) -#if MIN_VERSION_GLASGOW_HASKELL(8,8,1,0) import Servant.API (WithStatus (..)) -#endif +import Servant.Types.SourceT (SourceT) -- | Pretend that 'SourceT m a' is '[a]'. -- @@ -19,7 +16,5 @@ import Servant.API (WithStatus (..)) instance ToSchema a => ToSchema (SourceT m a) where declareNamedSchema _ = declareNamedSchema (Proxy :: Proxy [a]) -#if MIN_VERSION_GLASGOW_HASKELL(8,8,1,0) -- @since 1.1.11 deriving instance ToSchema a => ToSchema (WithStatus s a) -#endif diff --git a/servant-swagger/src/Servant/Swagger/Internal/Test.hs b/servant-swagger/src/Servant/Swagger/Internal/Test.hs index 19ace24ab..05f8f5435 100644 --- a/servant-swagger/src/Servant/Swagger/Internal/Test.hs +++ b/servant-swagger/src/Servant/Swagger/Internal/Test.hs @@ -150,7 +150,7 @@ props _ f px = sequence_ specs specs = tmapEvery (Proxy :: Proxy (Typeable ': Show ': Arbitrary ': cs)) aprop px aprop :: forall p' a. (Arbitrary a, EveryTF cs a, Show a, Typeable a) => p' a -> Spec - aprop _ = prop (show (typeOf (undefined :: a))) (f :: a -> Property) + aprop _ = prop (show (typeRep (Proxy :: Proxy a))) (f :: a -> Property) -- | Pretty print validation errors -- together with actual JSON and Swagger Schema diff --git a/servant-swagger/src/Servant/Swagger/Internal/TypeLevel/API.hs b/servant-swagger/src/Servant/Swagger/Internal/TypeLevel/API.hs index bfb296f22..95dbe8ba7 100644 --- a/servant-swagger/src/Servant/Swagger/Internal/TypeLevel/API.hs +++ b/servant-swagger/src/Servant/Swagger/Internal/TypeLevel/API.hs @@ -1,6 +1,5 @@ {-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE DataKinds #-} -{-# LANGUAGE KindSignatures #-} {-# LANGUAGE PolyKinds #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeOperators #-} diff --git a/servant-swagger/src/Servant/Swagger/Internal/TypeLevel/Every.hs b/servant-swagger/src/Servant/Swagger/Internal/TypeLevel/Every.hs index c485b06f7..663070904 100644 --- a/servant-swagger/src/Servant/Swagger/Internal/TypeLevel/Every.hs +++ b/servant-swagger/src/Servant/Swagger/Internal/TypeLevel/Every.hs @@ -4,8 +4,6 @@ {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE GADTs #-} -{-# LANGUAGE InstanceSigs #-} -{-# LANGUAGE KindSignatures #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE PolyKinds #-} {-# LANGUAGE RankNTypes #-} diff --git a/servant-swagger/src/Servant/Swagger/Internal/TypeLevel/TMap.hs b/servant-swagger/src/Servant/Swagger/Internal/TypeLevel/TMap.hs index 28b6a1d60..9857bdb5c 100644 --- a/servant-swagger/src/Servant/Swagger/Internal/TypeLevel/TMap.hs +++ b/servant-swagger/src/Servant/Swagger/Internal/TypeLevel/TMap.hs @@ -1,7 +1,6 @@ {-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE FlexibleInstances #-} -{-# LANGUAGE KindSignatures #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE PolyKinds #-} {-# LANGUAGE RankNTypes #-} diff --git a/servant-swagger/test/Servant/SwaggerSpec.hs b/servant-swagger/test/Servant/SwaggerSpec.hs index b73793de9..a2d5a2836 100644 --- a/servant-swagger/test/Servant/SwaggerSpec.hs +++ b/servant-swagger/test/Servant/SwaggerSpec.hs @@ -430,7 +430,7 @@ getPostAPI = -- UVerb API -- ======================================================================= -data Lunch = Lunch {name :: String} +newtype Lunch = Lunch {name :: String} deriving (Eq, Generic, Show) instance ToSchema Lunch diff --git a/servant/src/Servant/API/Modifiers.hs b/servant/src/Servant/API/Modifiers.hs index 93fc448a3..25d76ada4 100644 --- a/servant/src/Servant/API/Modifiers.hs +++ b/servant/src/Servant/API/Modifiers.hs @@ -119,9 +119,9 @@ unfoldRequiredArgument unfoldRequiredArgument _ errReq errSt mex = case (sbool :: SBool (FoldRequired mods), mex) of (STrue, Nothing) -> errReq - (SFalse, Nothing) -> return Nothing - (STrue, Just ex) -> either errSt return ex - (SFalse, Just ex) -> either errSt (return . Just) ex + (SFalse, Nothing) -> pure Nothing + (STrue, Just ex) -> either errSt pure ex + (SFalse, Just ex) -> either errSt (pure . Just) ex -- | Helper type alias. -- @@ -155,11 +155,11 @@ unfoldRequestArgument unfoldRequestArgument _ errReq errSt mex = case (sbool :: SBool (FoldRequired mods), mex, sbool :: SBool (FoldLenient mods)) of (STrue, Nothing, _) -> errReq - (SFalse, Nothing, _) -> return Nothing - (STrue, Just ex, STrue) -> return ex - (STrue, Just ex, SFalse) -> either errSt return ex - (SFalse, Just ex, STrue) -> return (Just ex) - (SFalse, Just ex, SFalse) -> either errSt (return . Just) ex + (SFalse, Nothing, _) -> pure Nothing + (STrue, Just ex, STrue) -> pure ex + (STrue, Just ex, SFalse) -> either errSt pure ex + (SFalse, Just ex, STrue) -> pure (Just ex) + (SFalse, Just ex, SFalse) -> either errSt (pure . Just) ex -- $setup -- >>> import Servant.API diff --git a/servant/src/Servant/API/MultiVerb.hs b/servant/src/Servant/API/MultiVerb.hs index a4e4bacfb..45ea5a816 100644 --- a/servant/src/Servant/API/MultiVerb.hs +++ b/servant/src/Servant/API/MultiVerb.hs @@ -105,7 +105,6 @@ instance Applicative UnrenderResult where (<*>) = ap instance Monad UnrenderResult where - return = pure StatusMismatch >>= _ = StatusMismatch UnrenderError e >>= _ = UnrenderError e UnrenderSuccess x >>= f = f x diff --git a/servant/src/Servant/API/QueryString.hs b/servant/src/Servant/API/QueryString.hs index 2999858a6..33bfeb2d1 100644 --- a/servant/src/Servant/API/QueryString.hs +++ b/servant/src/Servant/API/QueryString.hs @@ -4,7 +4,6 @@ {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE PolyKinds #-} {-# LANGUAGE TupleSections #-} -{-# LANGUAGE TypeOperators #-} {-# OPTIONS_HADDOCK not-home #-} module Servant.API.QueryString (QueryString, DeepQuery, FromDeepQuery (..), ToDeepQuery (..), generateDeepParam) where diff --git a/servant/src/Servant/API/Stream.hs b/servant/src/Servant/API/Stream.hs index 7d1fd33c3..d44ba4aad 100644 --- a/servant/src/Servant/API/Stream.hs +++ b/servant/src/Servant/API/Stream.hs @@ -19,8 +19,6 @@ module Servant.API.Stream -- * Source - -- - -- | 'SourceIO' are equivalent to some *source* in streaming libraries. , SourceIO , ToSourceIO (..) @@ -41,6 +39,7 @@ module Servant.API.Stream where import Control.Applicative ((<|>)) +import Control.Monad import Control.Monad.IO.Class (MonadIO (..)) import qualified Data.Attoparsec.ByteString as A import qualified Data.Attoparsec.ByteString.Char8 as A8 @@ -113,12 +112,12 @@ class FromSourceIO chunk a | a -> chunk where fromSourceIO :: SourceIO chunk -> IO a instance MonadIO m => FromSourceIO a (SourceT m a) where - fromSourceIO = return . sourceFromSourceIO + fromSourceIO = pure . sourceFromSourceIO sourceFromSourceIO :: forall m a. MonadIO m => SourceT IO a -> SourceT m a sourceFromSourceIO src = SourceT $ \k -> - k $ Effect $ liftIO $ unSourceT src (return . go) + k $ Effect $ liftIO $ unSourceT src (pure . go) where go :: StepT IO a -> StepT m a go Stop = Stop @@ -193,7 +192,7 @@ instance FramingRender NewlineFraming where instance FramingUnrender NewlineFraming where framingUnrender _ f = transformWithAtto $ do bs <- A.takeWhile (/= 10) - () <$ A.word8 10 <|> A.endOfInput + void (A.word8 10) <|> A.endOfInput either fail pure (f (LBS.fromStrict bs)) ------------------------------------------------------------------------------- diff --git a/servant/src/Servant/Types/SourceT.hs b/servant/src/Servant/Types/SourceT.hs index 3e49e666f..72f0d2917 100644 --- a/servant/src/Servant/Types/SourceT.hs +++ b/servant/src/Servant/Types/SourceT.hs @@ -85,9 +85,7 @@ instance MFunctor SourceT where hoist f (SourceT m) = SourceT $ \k -> k $ Effect $ - f $ - fmap (hoist f) $ - m pure + f (hoist f <$> m pure) -- | >>> source "xy" <> source "z" :: SourceT Identity Char -- fromStepT (Effect (Identity (Yield 'x' (Yield 'y' (Yield 'z' Stop))))) diff --git a/servant/test/Servant/API/StreamSpec.hs b/servant/test/Servant/API/StreamSpec.hs index 656293c44..fc3a8cfc8 100644 --- a/servant/test/Servant/API/StreamSpec.hs +++ b/servant/test/Servant/API/StreamSpec.hs @@ -87,8 +87,9 @@ roundtrip render unrender xs = runRenderFrames :: (SourceT Identity a -> SourceT Identity LBS.ByteString) -> [a] -> Either String LBS.ByteString runRenderFrames f = fmap mconcat . runExcept . runSourceT . f . source +{- HLINT ignore runUnrenderFrames "Avoid lambda using `infix`" -} runUnrenderFrames :: (SourceT Identity b -> SourceT Identity a) -> [b] -> [Either String a] -runUnrenderFrames f = go . Effect . (\x -> unSourceT x return) . f . source +runUnrenderFrames f = go . Effect . (\x -> unSourceT x pure) . f . source where go :: StepT Identity a -> [Either String a] go Stop = []