servant-server-0.11: A family of combinators for defining webservices APIs and serving them

Safe Haskell | Safe
Language | Haskell2010

Servant.Server.Internal.Context

Contents

- support for named subcontexts

Synopsis

- data Context contextTypes where
  - EmptyContext :: Context '[]
  - (:.) :: x -> Context xs -> Context (x ': xs)
- class HasContextEntry context val where
- data NamedContext name subContext = NamedContext (Context subContext)
- descendIntoNamedContext :: forall context name subContext. HasContextEntry context (NamedContext name subContext) => Proxy (name :: Symbol) -> Context context -> Context subContext

# Documentation

data Context contextTypes where #

`Context`s are used to pass values to combinators. (They are not meant to be used to pass parameters to your handlers, i.e. they should not replace any custom `ReaderT`-monad-stack that you're using with `Enter`.) If you don't use combinators that require any context entries, you can just use `serve` as always.

If you are using combinators that require a non-empty `Context` you have to use `serveWithContext` and pass it a `Context` that contains all the values your combinators need. A `Context` is essentially a heterogenous list and accessing the elements is being done by type (see `getContextEntry`). The parameter of the type `Context` is a type-level list reflecting the types of the contained context entries. To create a `Context` with entries, use the operator `(`:.`)`:

    >>> :type True :. () :. EmptyContext
    True :. () :. EmptyContext :: Context '[Bool, ()]

Constructors

EmptyContext :: Context '[] |
(:.) :: x -> Context xs -> Context (x ': xs) infixr 5 |

Instances

(Eq a, Eq (Context as)) => Eq (Context ((:) * a as)) # |
Methods (==) :: Context ((* ': a) as) -> Context ((* ': a) as) -> Bool # (/=) :: Context ((* ': a) as) -> Context ((* ': a) as) -> Bool #
Eq (Context ([] *)) # |
Methods (==) :: Context [*] -> Context [*] -> Bool # (/=) :: Context [*] -> Context [*] -> Bool #
(Show a, Show (Context as)) => Show (Context ((:) * a as)) # |
Methods showsPrec :: Int -> Context ((* ': a) as) -> ShowS # show :: Context ((* ': a) as) -> String # showList :: [Context ((* ': a) as)] -> ShowS #
Show (Context ([] *)) # |
Methods showsPrec :: Int -> Context [*] -> ShowS # show :: Context [*] -> String # showList :: [Context [*]] -> ShowS #

class HasContextEntry context val where #

This class is used to access context entries in `Context`s. `getContextEntry` returns the first value where the type matches:

    >>> getContextEntry (True :. False :. EmptyContext) :: Bool
    True

If the `Context` does not contain an entry of the requested type, you'll get an error:

    >>> getContextEntry (True :. False :. EmptyContext) :: String
    ...
    ...No instance for (HasContextEntry '[] [Char])
    ...

Minimal complete definition

getContextEntry

Methods

getContextEntry :: Context context -> val #

Instances

HasContextEntry ((:) * val xs) val # |
Methods getContextEntry :: Context ((* ': val) xs) -> val #
HasContextEntry xs val => HasContextEntry ((:) * notIt xs) val # |
Methods getContextEntry :: Context ((* ': notIt) xs) -> val #

# support for named subcontexts

data NamedContext name subContext #

Normally context entries are accessed by their types. In case you need to have multiple values of the same type in your `Context` and need to access them, we provide `NamedContext`. You can think of it as sub-namespaces for `Context`s.

Constructors

NamedContext (Context subContext) |

descendIntoNamedContext :: forall context name subContext. HasContextEntry context (NamedContext name subContext) => Proxy (name :: Symbol) -> Context context -> Context subContext #

`descendIntoNamedContext` allows you to access `NamedContext`s. Usually you won't have to use it yourself but instead use a combinator like `WithNamedContext`.

This is how `descendIntoNamedContext` works:

    >>> :set -XFlexibleContexts
    >>> let subContext = True :. EmptyContext
    >>> :type subContext
    subContext :: Context '[Bool]
    >>> let parentContext = False :. (NamedContext subContext :: NamedContext "subContext" '[Bool]) :. EmptyContext
    >>> :type parentContext
    parentContext :: Context '[Bool, NamedContext "subContext" '[Bool]]
    >>> descendIntoNamedContext (Proxy :: Proxy "subContext") parentContext :: Context '[Bool]
    True :. EmptyContext