@@ -68,7 +68,7 @@ need to have some language extensions and imports:
68> import qualified Data.Aeson.Parser
68> import qualified Data.Aeson.Parser
69> import qualified Text.Blaze.Html
69> import qualified Text.Blaze.Html
71−``` haskell
71+``` haskell ignore
72{-# LANGUAGE TypeFamilies #-}
72{-# LANGUAGE TypeFamilies #-}
@@ -107,7 +107,7 @@ Nothing funny going on here. But we now can define our list of two users.
108Let's also write our API type.
108Let's also write our API type.
110−``` haskell
110+``` haskell ignore
111type UserAPI1 = "users" :> Get '[JSON] [User]
111type UserAPI1 = "users" :> Get '[JSON] [User]
@@ -324,7 +324,7 @@ decided to provide a pair of typeclasses, `FromText` and `ToText` which just
324let you say that you can respectively *extract* or *encode* values of some type
324let you say that you can respectively *extract* or *encode* values of some type
325*from*/*to* text. Here are the definitions:
325*from*/*to* text. Here are the definitions:
327−``` haskell
327+``` haskell ignore
328class FromText a where
328class FromText a where
329 fromText :: Text -> Maybe a
329 fromText :: Text -> Maybe a
@@ -363,7 +363,7 @@ your own.
364or writing the instances by hand:
364or writing the instances by hand:
366−``` haskell
366+``` haskell ignore
367instance FromText UserId where
367instance FromText UserId where
368 fromText = fmap UserId fromText
368 fromText = fmap UserId fromText
@@ -394,7 +394,7 @@ The truth behind `JSON`
394What exactly is `JSON`? Like the 3 other content types provided out of the box
394What exactly is `JSON`? Like the 3 other content types provided out of the box
395by *servant*, it's a really dumb data type.
395by *servant*, it's a really dumb data type.
397−``` haskell
397+``` haskell ignore
399data PlainText
399data PlainText
400data FormUrlEncoded
400data FormUrlEncoded
@@ -415,7 +415,7 @@ haddocks from this link, you can see that we just have to specify
415use `(//) :: ByteString -> ByteString -> MediaType`. The precise way to specify
415use `(//) :: ByteString -> ByteString -> MediaType`. The precise way to specify
416the `MediaType` is to write an instance for the `Accept` class:
416the `MediaType` is to write an instance for the `Accept` class:
418−``` haskell
418+``` haskell ignore
419-- for reference:
419-- for reference:
420class Accept ctype where
420class Accept ctype where
421 contentType :: Proxy ctype -> MediaType
421 contentType :: Proxy ctype -> MediaType
@@ -428,7 +428,7 @@ The second step is centered around the `MimeRender` and `MimeUnrender` classes.
428These classes just let you specify a way to respectively encode and decode
428These classes just let you specify a way to respectively encode and decode
429values respectively into or from your content-type's representation.
429values respectively into or from your content-type's representation.
431−``` haskell
431+``` haskell ignore
432class Accept ctype => MimeRender ctype a where
432class Accept ctype => MimeRender ctype a where
433 mimeRender :: Proxy ctype -> a -> ByteString
433 mimeRender :: Proxy ctype -> a -> ByteString
434 -- alternatively readable as:
434 -- alternatively readable as:
@@ -442,7 +442,7 @@ In the case of `JSON`, this is easily dealt with! For any type `a` with a
442`ToJSON` instance, we can render values of that type to JSON using
442`ToJSON` instance, we can render values of that type to JSON using
443`Data.Aeson.encode`.
443`Data.Aeson.encode`.
445−``` haskell
445+``` haskell ignore
446instance ToJSON a => MimeRender JSON a where
446instance ToJSON a => MimeRender JSON a where
447 mimeRender _ = encode
447 mimeRender _ = encode
@@ -450,7 +450,7 @@ instance ToJSON a => MimeRender JSON a where
450And now the `MimeUnrender` class, which lets us extract values from lazy
450And now the `MimeUnrender` class, which lets us extract values from lazy
451`ByteString`s, alternatively failing with an error string.
451`ByteString`s, alternatively failing with an error string.
453−``` haskell
453+``` haskell ignore
454class Accept ctype => MimeUnrender ctype a where
454class Accept ctype => MimeUnrender ctype a where
455 mimeUnrender :: Proxy ctype -> ByteString -> Either String a
455 mimeUnrender :: Proxy ctype -> ByteString -> Either String a
456 -- alternatively:
456 -- alternatively:
@@ -471,7 +471,7 @@ you are curious.
472This function is exactly what we need for our `MimeUnrender` instance.
472This function is exactly what we need for our `MimeUnrender` instance.
474−``` haskell
474+``` haskell ignore
475instance FromJSON a => MimeUnrender JSON a where
475instance FromJSON a => MimeUnrender JSON a where
476 mimeUnrender _ = eitherDecodeLenient
476 mimeUnrender _ = eitherDecodeLenient
@@ -627,7 +627,7 @@ as interfaces to databases that we interact with in `IO`;
628Let's recall some definitions.
628Let's recall some definitions.
630−``` haskell
630+``` haskell ignore
631-- from the Prelude
631-- from the Prelude
632data Either e a = Left e | Right a
632data Either e a = Left e | Right a
@@ -644,7 +644,7 @@ action that either returns an error or a result.
644The aforementioned `either` package is worth taking a look at. Perhaps most
644The aforementioned `either` package is worth taking a look at. Perhaps most
645importantly:
645importantly:
647−``` haskell
647+``` haskell ignore
648left :: Monad m => e -> EitherT e m a
648left :: Monad m => e -> EitherT e m a
650Allows you to return an error from your handler (whereas `return` is enough to
650Allows you to return an error from your handler (whereas `return` is enough to
@@ -659,7 +659,7 @@ Performing IO
660Another 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:
660Another 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:
662−``` haskell
662+``` haskell ignore
663class Monad m => MonadIO m where
663class Monad m => MonadIO m where
664 liftIO :: IO a -> m a
664 liftIO :: IO a -> m a
@@ -688,7 +688,7 @@ error message, all you have to do is use the `left` function mentioned above
688and provide it with the appropriate value of type `ServantErr`, which is
688and provide it with the appropriate value of type `ServantErr`, which is
689defined as:
689defined as:
691−``` haskell
691+``` haskell ignore
692data ServantErr = ServantErr
692data ServantErr = ServantErr
693 { errHTTPCode :: Int
693 { errHTTPCode :: Int
694 , errReasonPhrase :: String
694 , errReasonPhrase :: String
@@ -773,7 +773,7 @@ under some path in your web API. As mentioned earlier in this document, the
773application". Well, servant-server provides a function to get a file and
773application". Well, servant-server provides a function to get a file and
774directory serving WAI application, namely:
774directory serving WAI application, namely:
776−``` haskell
776+``` haskell ignore
777-- exported by Servant and Servant.Server
777-- exported by Servant and Servant.Server
778serveDirectory :: FilePath -> Server Raw
778serveDirectory :: FilePath -> Server Raw
@@ -809,7 +809,7 @@ In other words:
810Here is our little server in action.
810Here is our little server in action.
812−``` haskell
812+``` haskell ignore
813$ curl http://localhost:8081/code/T1.hs
813$ curl http://localhost:8081/code/T1.hs
814{-# LANGUAGE DataKinds #-}
814{-# LANGUAGE DataKinds #-}
815{-# LANGUAGE TypeFamilies #-}
815{-# LANGUAGE TypeFamilies #-}
@@ -918,7 +918,7 @@ We can instead factor out the `userid`:
919However, you have to be aware that this has an effect on the type of the corresponding `Server`:
919However, you have to be aware that this has an effect on the type of the corresponding `Server`:
921−``` haskell
921+``` haskell ignore
922Server UserAPI3 = (Int -> EitherT ServantErr IO User)
922Server UserAPI3 = (Int -> EitherT ServantErr IO User)
923 :<|> (Int -> EitherT ServantErr IO ())
923 :<|> (Int -> EitherT ServantErr IO ())
@@ -1076,7 +1076,7 @@ Using another monad for your handlers
1077Remember 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.
1077Remember 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.
1079−``` haskell
1079+``` haskell ignore
1080type Server api = ServerT api (EitherT ServantErr IO)
1080type Server api = ServerT api (EitherT ServantErr IO)
@@ -1090,7 +1090,7 @@ Natural transformations
1090If we have a function that gets us from an `m a` to an `n a`, for any `a`, what
1090If we have a function that gets us from an `m a` to an `n a`, for any `a`, what
1091do we have?
1091do we have?
1093−``` haskell
1093+``` haskell ignore
1094newtype m :~> n = Nat { unNat :: forall a. m a -> n a}
1094newtype m :~> n = Nat { unNat :: forall a. m a -> n a}
1096-- For example
1096-- For example
@@ -1103,7 +1103,7 @@ So if you want to write handlers using another monad/type than `EitherT
1103ServantErr IO`, say the `Reader String` monad, the first thing you have to
1103ServantErr IO`, say the `Reader String` monad, the first thing you have to
1104prepare is a function:
1104prepare is a function:
1106−``` haskell
1106+``` haskell ignore
1107readerToEither :: Reader String :~> EitherT ServantErr IO
1107readerToEither :: Reader String :~> EitherT ServantErr IO