Explicit ignore
This commit is contained in:
parent
5542ce8916
commit
7af73d63ea
5 changed files with 30 additions and 30 deletions
|
@ -88,7 +88,7 @@ them amounts to `/`-separating them in a URL.
|
|||
These 5 combinators are very similar except that they each describe a
|
||||
different HTTP method. This is how they're declared
|
||||
|
||||
``` haskell
|
||||
``` haskell ignore
|
||||
data Delete (contentTypes :: [*]) a
|
||||
data Get (contentTypes :: [*]) a
|
||||
data Patch (contentTypes :: [*]) a
|
||||
|
@ -116,7 +116,7 @@ The `Capture` combinator in servant takes a (type-level) string representing
|
|||
the "name of the variable" and a type, which indicates the type we want to
|
||||
decode the "captured value" to.
|
||||
|
||||
``` haskell
|
||||
``` haskell ignore
|
||||
data Capture (s :: Symbol) a
|
||||
-- s :: Symbol just says that 's' must be a type-level string.
|
||||
```
|
||||
|
@ -153,7 +153,7 @@ active users whereas `/users` would list them all.
|
|||
|
||||
Here are the corresponding data type declarations:
|
||||
|
||||
``` haskell
|
||||
``` haskell ignore
|
||||
data QueryParam (sym :: Symbol) a
|
||||
data QueryParams (sym :: Symbol) a
|
||||
data QueryFlag (sym :: Symbol)
|
||||
|
@ -171,7 +171,7 @@ after *January 1st, 2005*.
|
|||
|
||||
Corresponding data type declarations below.
|
||||
|
||||
``` haskell
|
||||
``` haskell ignore
|
||||
data MatrixParam (sym :: Symbol) a
|
||||
data MatrixParams (sym :: Symbol) a
|
||||
data MatrixFlag (sym :: Symbol)
|
||||
|
@ -206,7 +206,7 @@ Request` or `Unsupported Content Type` as appropriate.
|
|||
|
||||
Here's the data type declaration for it:
|
||||
|
||||
``` haskell
|
||||
``` haskell ignore
|
||||
data ReqBody (contentTypes :: [*]) a
|
||||
```
|
||||
|
||||
|
@ -235,7 +235,7 @@ The `Header` combinator in servant takes a type-level string for the header
|
|||
name and the type to which we want to decode the header's value (from some
|
||||
textual representation), as illustrated below:
|
||||
|
||||
``` haskell
|
||||
``` haskell ignore
|
||||
data Header (sym :: Symbol) a
|
||||
```
|
||||
|
||||
|
@ -274,7 +274,7 @@ headers too. *servant* provides a `Headers` combinator that carries a list of
|
|||
`Header` and can be used by simply wrapping the "return type" of an endpoint
|
||||
with it.
|
||||
|
||||
``` haskell
|
||||
``` haskell ignore
|
||||
data Headers (ls :: [*]) a
|
||||
```
|
||||
|
||||
|
|
|
@ -83,7 +83,7 @@ Each function makes available as an argument any value that the response may dep
|
|||
|
||||
As you can see in the code above, we just "pattern match our way" to these functions. If we try to derive less or more functions than there are endpoints in the API, we obviously get an error. The `BaseUrl` value there is just:
|
||||
|
||||
``` haskell
|
||||
``` haskell ignore
|
||||
-- | URI scheme to use
|
||||
data Scheme =
|
||||
Http -- ^ http://
|
||||
|
|
|
@ -26,5 +26,5 @@ convert =
|
|||
go :: [String] -> [String]
|
||||
go (a : r)
|
||||
| ">" `isPrefixOf` a
|
||||
= "``` haskell" : map (drop 2) (a : r) ++ "```" : []
|
||||
= "``` haskell ignore" : map (drop 2) (a : r) ++ "```" : []
|
||||
go x = x
|
||||
|
|
|
@ -94,7 +94,7 @@ With all of this, we can derive docs for our API.
|
|||
|
||||
*servant*'s markdown pretty printer is a function named `markdown`.
|
||||
|
||||
``` haskell
|
||||
``` haskell ignore
|
||||
markdown :: API -> String
|
||||
```
|
||||
|
||||
|
|
|
@ -68,7 +68,7 @@ need to have some language extensions and imports:
|
|||
> import qualified Data.Aeson.Parser
|
||||
> import qualified Text.Blaze.Html
|
||||
|
||||
``` haskell
|
||||
``` haskell ignore
|
||||
{-# LANGUAGE TypeFamilies #-}
|
||||
```
|
||||
|
||||
|
@ -107,7 +107,7 @@ Nothing funny going on here. But we now can define our list of two users.
|
|||
|
||||
Let's also write our API type.
|
||||
|
||||
``` haskell
|
||||
``` haskell ignore
|
||||
type UserAPI1 = "users" :> Get '[JSON] [User]
|
||||
```
|
||||
|
||||
|
@ -324,7 +324,7 @@ decided to provide a pair of typeclasses, `FromText` and `ToText` which just
|
|||
let you say that you can respectively *extract* or *encode* values of some type
|
||||
*from*/*to* text. Here are the definitions:
|
||||
|
||||
``` haskell
|
||||
``` haskell ignore
|
||||
class FromText a where
|
||||
fromText :: Text -> Maybe a
|
||||
|
||||
|
@ -363,7 +363,7 @@ your own.
|
|||
|
||||
or writing the instances by hand:
|
||||
|
||||
``` haskell
|
||||
``` haskell ignore
|
||||
instance FromText UserId where
|
||||
fromText = fmap UserId fromText
|
||||
|
||||
|
@ -394,7 +394,7 @@ The truth behind `JSON`
|
|||
What exactly is `JSON`? Like the 3 other content types provided out of the box
|
||||
by *servant*, it's a really dumb data type.
|
||||
|
||||
``` haskell
|
||||
``` haskell ignore
|
||||
data JSON
|
||||
data PlainText
|
||||
data FormUrlEncoded
|
||||
|
@ -415,7 +415,7 @@ haddocks from this link, you can see that we just have to specify
|
|||
use `(//) :: ByteString -> ByteString -> MediaType`. The precise way to specify
|
||||
the `MediaType` is to write an instance for the `Accept` class:
|
||||
|
||||
``` haskell
|
||||
``` haskell ignore
|
||||
-- for reference:
|
||||
class Accept ctype where
|
||||
contentType :: Proxy ctype -> MediaType
|
||||
|
@ -428,7 +428,7 @@ The second step is centered around the `MimeRender` and `MimeUnrender` classes.
|
|||
These classes just let you specify a way to respectively encode and decode
|
||||
values respectively into or from your content-type's representation.
|
||||
|
||||
``` haskell
|
||||
``` haskell ignore
|
||||
class Accept ctype => MimeRender ctype a where
|
||||
mimeRender :: Proxy ctype -> a -> ByteString
|
||||
-- alternatively readable as:
|
||||
|
@ -442,7 +442,7 @@ In the case of `JSON`, this is easily dealt with! For any type `a` with a
|
|||
`ToJSON` instance, we can render values of that type to JSON using
|
||||
`Data.Aeson.encode`.
|
||||
|
||||
``` haskell
|
||||
``` haskell ignore
|
||||
instance ToJSON a => MimeRender JSON a where
|
||||
mimeRender _ = encode
|
||||
```
|
||||
|
@ -450,7 +450,7 @@ instance ToJSON a => MimeRender JSON a where
|
|||
And now the `MimeUnrender` class, which lets us extract values from lazy
|
||||
`ByteString`s, alternatively failing with an error string.
|
||||
|
||||
``` haskell
|
||||
``` haskell ignore
|
||||
class Accept ctype => MimeUnrender ctype a where
|
||||
mimeUnrender :: Proxy ctype -> ByteString -> Either String a
|
||||
-- alternatively:
|
||||
|
@ -471,7 +471,7 @@ you are curious.
|
|||
|
||||
This function is exactly what we need for our `MimeUnrender` instance.
|
||||
|
||||
``` haskell
|
||||
``` haskell ignore
|
||||
instance FromJSON a => MimeUnrender JSON a where
|
||||
mimeUnrender _ = eitherDecodeLenient
|
||||
```
|
||||
|
@ -627,7 +627,7 @@ as interfaces to databases that we interact with in `IO`;
|
|||
|
||||
Let's recall some definitions.
|
||||
|
||||
``` haskell
|
||||
``` haskell ignore
|
||||
-- from the Prelude
|
||||
data Either e a = Left e | Right a
|
||||
|
||||
|
@ -644,7 +644,7 @@ action that either returns an error or a result.
|
|||
The aforementioned `either` package is worth taking a look at. Perhaps most
|
||||
importantly:
|
||||
|
||||
``` haskell
|
||||
``` haskell ignore
|
||||
left :: Monad m => e -> EitherT e m a
|
||||
```
|
||||
Allows you to return an error from your handler (whereas `return` is enough to
|
||||
|
@ -659,7 +659,7 @@ Performing IO
|
|||
|
||||
Another important instance from the list above is `MonadIO m => MonadIO (EitherT e m)`. [`MonadIO`](http://hackage.haskell.org/package/transformers-0.4.3.0/docs/Control-Monad-IO-Class.html) is a class from the *transformers* package defined as:
|
||||
|
||||
``` haskell
|
||||
``` haskell ignore
|
||||
class Monad m => MonadIO m where
|
||||
liftIO :: IO a -> m a
|
||||
```
|
||||
|
@ -688,7 +688,7 @@ error message, all you have to do is use the `left` function mentioned above
|
|||
and provide it with the appropriate value of type `ServantErr`, which is
|
||||
defined as:
|
||||
|
||||
``` haskell
|
||||
``` haskell ignore
|
||||
data ServantErr = ServantErr
|
||||
{ errHTTPCode :: Int
|
||||
, errReasonPhrase :: String
|
||||
|
@ -773,7 +773,7 @@ under some path in your web API. As mentioned earlier in this document, the
|
|||
application". Well, servant-server provides a function to get a file and
|
||||
directory serving WAI application, namely:
|
||||
|
||||
``` haskell
|
||||
``` haskell ignore
|
||||
-- exported by Servant and Servant.Server
|
||||
serveDirectory :: FilePath -> Server Raw
|
||||
```
|
||||
|
@ -809,7 +809,7 @@ In other words:
|
|||
|
||||
Here is our little server in action.
|
||||
|
||||
``` haskell
|
||||
``` haskell ignore
|
||||
$ curl http://localhost:8081/code/T1.hs
|
||||
{-# LANGUAGE DataKinds #-}
|
||||
{-# LANGUAGE TypeFamilies #-}
|
||||
|
@ -918,7 +918,7 @@ We can instead factor out the `userid`:
|
|||
|
||||
However, you have to be aware that this has an effect on the type of the corresponding `Server`:
|
||||
|
||||
``` haskell
|
||||
``` haskell ignore
|
||||
Server UserAPI3 = (Int -> EitherT ServantErr IO User)
|
||||
:<|> (Int -> EitherT ServantErr IO ())
|
||||
|
||||
|
@ -1076,7 +1076,7 @@ Using another monad for your handlers
|
|||
|
||||
Remember how `Server` turns combinators for HTTP methods into `EitherT ServantErr IO`? Well, actually, there's more to that. `Server` is actually a simple type synonym.
|
||||
|
||||
``` haskell
|
||||
``` haskell ignore
|
||||
type Server api = ServerT api (EitherT ServantErr IO)
|
||||
```
|
||||
|
||||
|
@ -1090,7 +1090,7 @@ Natural transformations
|
|||
If we have a function that gets us from an `m a` to an `n a`, for any `a`, what
|
||||
do we have?
|
||||
|
||||
``` haskell
|
||||
``` haskell ignore
|
||||
newtype m :~> n = Nat { unNat :: forall a. m a -> n a}
|
||||
|
||||
-- For example
|
||||
|
@ -1103,7 +1103,7 @@ So if you want to write handlers using another monad/type than `EitherT
|
|||
ServantErr IO`, say the `Reader String` monad, the first thing you have to
|
||||
prepare is a function:
|
||||
|
||||
``` haskell
|
||||
``` haskell ignore
|
||||
readerToEither :: Reader String :~> EitherT ServantErr IO
|
||||
```
|
||||
|
||||
|
|
Loading…
Reference in a new issue