Safe Haskell | None |
---|---|
Language | Haskell98 |
This module defines the Monad stack used by Happstack. You mostly don't want to be looking in here. Look in Happstack.Server.Monads instead.
- type Web a = WebT IO a
- type ServerPart a = ServerPartT IO a
- newtype ServerPartT m a = ServerPartT {
- unServerPartT :: ReaderT Request (WebT m) a
- runServerPartT :: ServerPartT m a -> Request -> WebT m a
- withRequest :: (Request -> WebT m a) -> ServerPartT m a
- anyRequest :: Monad m => WebT m a -> ServerPartT m a
- mapServerPartT :: (UnWebT m a -> UnWebT n b) -> ServerPartT m a -> ServerPartT n b
- mapServerPartT' :: (Request -> UnWebT m a -> UnWebT n b) -> ServerPartT m a -> ServerPartT n b
- class Monad m => ServerMonad m where
- smAskRqEnv :: (ServerMonad m, MonadIO m) => m ([(String, Input)], Maybe [(String, Input)], [(String, Cookie)])
- smLocalRqEnv :: (ServerMonad m, MonadIO m) => (([(String, Input)], Maybe [(String, Input)], [(String, Cookie)]) -> ([(String, Input)], Maybe [(String, Input)], [(String, Cookie)])) -> m b -> m b
- data SetAppend a
- extract :: SetAppend t -> t
- type FilterFun a = SetAppend (Dual (Endo a))
- unFilterFun :: FilterFun a -> a -> a
- filterFun :: (a -> a) -> FilterFun a
- newtype FilterT a m b = FilterT {}
- class Monad m => FilterMonad a m | m -> a where
- setFilter :: (a -> a) -> m ()
- composeFilter :: (a -> a) -> m ()
- getFilter :: m b -> m (b, a -> a)
- ignoreFilters :: FilterMonad a m => m ()
- newtype WebT m a = WebT {}
- type UnWebT m a = m (Maybe (Either Response a, FilterFun Response))
- class Monad m => WebMonad a m | m -> a where
- finishWith :: a -> m b
- escape :: (WebMonad a m, FilterMonad a m) => m a -> m b
- escape' :: (WebMonad a m, FilterMonad a m) => a -> m b
- ununWebT :: WebT m a -> UnWebT m a
- mkWebT :: UnWebT m a -> WebT m a
- mapWebT :: (UnWebT m a -> UnWebT n b) -> WebT m a -> WebT n b
- localContext :: Monad m => (WebT m a -> WebT m' a) -> ServerPartT m a -> ServerPartT m' a
- multi :: (Monad m, MonadPlus m) => [ServerPartT m a] -> ServerPartT m a
- debugFilter :: (MonadIO m, Show a) => ServerPartT m a -> ServerPartT m a
- outputTraceMessage :: String -> a -> a
- mkFailMessage :: (FilterMonad Response m, WebMonad Response m) => String -> m b
- failResponse :: String -> Response
- failHtml :: String -> String
- escapeString :: String -> String
Documentation
type ServerPart a = ServerPartT IO a Source
An alias for ServerPartT
IO
newtype ServerPartT m a Source
ServerPartT
is a rich, featureful monad for web development.
see also: simpleHTTP
, ServerMonad
, FilterMonad
, WebMonad
, and HasRqData
ServerPartT | |
|
runServerPartT :: ServerPartT m a -> Request -> WebT m a Source
withRequest :: (Request -> WebT m a) -> ServerPartT m a Source
function for lifting WebT to ServerPartT
NOTE: This is mostly for internal use. If you want to access the
Request
in user-code see askRq
from ServerMonad
.
do request <- askRq ...
anyRequest :: Monad m => WebT m a -> ServerPartT m a Source
A constructor for a ServerPartT
when you don't care about the request.
NOTE: This is mostly for internal use. If you think you need to use it in your own code, you might consider asking on the mailing list or IRC to find out if there is an alternative solution.
mapServerPartT :: (UnWebT m a -> UnWebT n b) -> ServerPartT m a -> ServerPartT n b Source
Apply a function to transform the inner monad of
.ServerPartT
m
Often used when transforming a monad with ServerPartT
, since
simpleHTTP
requires a
. Refer to ServerPartT
IO
aUnWebT
for an explanation of the structure of the monad.
Here is an example. Suppose you want to embed an ErrorT
into your
ServerPartT
to enable throwError
and catchError
in your Monad
.
type MyServerPartT e m a = ServerPartT (ErrorT e m) a
Now suppose you want to pass MyServerPartT
into a function that
demands a
(e.g. ServerPartT
IO
asimpleHTTP
). You can
provide the function:
unpackErrorT :: (Monad m, Show e) => UnWebT (ErrorT e m) a -> UnWebT m a unpackErrorT et = do eitherV <- runErrorT et return $ case eitherV of Left err -> Just (Left $ toResponse $ "Catastrophic failure " ++ show err , filterFun $ \r -> r{rsCode = 500}) Right x -> x
With unpackErrorT
you can now call simpleHTTP
. Just wrap your
ServerPartT
list.
simpleHTTP nullConf $ mapServerPartT unpackErrorT (myPart `catchError` myHandler)
Or alternatively:
simpleHTTP' unpackErrorT nullConf (myPart `catchError` myHandler)
Also see spUnwrapErrorT
for a more sophisticated version of this
function.
mapServerPartT' :: (Request -> UnWebT m a -> UnWebT n b) -> ServerPartT m a -> ServerPartT n b Source
A variant of mapServerPartT
where the first argument also takes
a Request
. Useful if you want to runServerPartT
on a different
ServerPartT
inside your monad (see spUnwrapErrorT
).
class Monad m => ServerMonad m where Source
The ServerMonad
class provides methods for reading or locally
modifying the Request
. It is essentially a specialized version of
the MonadReader
class. Providing the unique names, askRq
and
localRq
makes it easier to use ServerPartT
and ReaderT
together.
Monad m => ServerMonad (ServerPartT m) | |
ServerMonad m => ServerMonad (ReaderT r m) | |
ServerMonad m => ServerMonad (StateT s m) | |
ServerMonad m => ServerMonad (StateT s m) | |
ServerMonad m => ServerMonad (ExceptT e m) | |
(Error e, ServerMonad m) => ServerMonad (ErrorT e m) | |
(ServerMonad m, Monoid w) => ServerMonad (WriterT w m) | |
(ServerMonad m, Monoid w) => ServerMonad (WriterT w m) | |
(ServerMonad m, Monoid w) => ServerMonad (RWST r w s m) | |
(ServerMonad m, Monoid w) => ServerMonad (RWST r w s m) |
smAskRqEnv :: (ServerMonad m, MonadIO m) => m ([(String, Input)], Maybe [(String, Input)], [(String, Cookie)]) Source
Implementation of askRqEnv
for arbitrary ServerMonad
.
smLocalRqEnv :: (ServerMonad m, MonadIO m) => (([(String, Input)], Maybe [(String, Input)], [(String, Cookie)]) -> ([(String, Input)], Maybe [(String, Input)], [(String, Cookie)])) -> m b -> m b Source
Implementation of localRqEnv
for arbitrary ServerMonad
.
A monoid operation container. If a
is a monoid, then
SetAppend
is a monoid with the following behaviors:
Set x `mappend` Append y = Set (x `mappend` y) Append x `mappend` Append y = Append (x `mappend` y) _ `mappend` Set y = Set y
A simple way of summarizing this is, if the right side is Append
,
then the right is appended to the left. If the right side is
Set
, then the left side is ignored.
extract :: SetAppend t -> t Source
Extract the value from a SetAppend
.
Note that a SetAppend
is actually a CoPointed
from:
http://hackage.haskell.org/packages/archive/category-extras/latest/doc/html/Control-Functor-Pointed.html
But lets not drag in that dependency. yet...
unFilterFun :: FilterFun a -> a -> a Source
filterFun :: (a -> a) -> FilterFun a Source
turn a function into a FilterFun
. Primarily used with mapServerPartT
MonadBase b m => MonadBase b (FilterT a m) | |
MonadBaseControl b m => MonadBaseControl b (FilterT a m) | |
Monad m => FilterMonad a (FilterT a m) | |
MonadTrans (FilterT a) | |
MonadTransControl (FilterT a) | |
Monad m => Monad (FilterT a m) | |
Functor m => Functor (FilterT a m) | |
Applicative m => Applicative (FilterT a m) | |
MonadThrow m => MonadThrow (FilterT a m) | |
MonadCatch m => MonadCatch (FilterT a m) | |
MonadIO m => MonadIO (FilterT a m) | |
type StT (FilterT a) b = StT (WriterT (FilterFun a)) b | |
type StM (FilterT a m) c = ComposeSt (FilterT a) m c |
class Monad m => FilterMonad a m | m -> a where Source
A set of functions for manipulating filters.
ServerPartT
implements FilterMonad
Response
so these methods
are the fundamental ways of manipulating Response
values.
setFilter :: (a -> a) -> m () Source
Ignores all previous alterations to your filter
As an example:
do composeFilter f setFilter g return "Hello World"
The
will cause the first setFilter
g
to
be ignored.composeFilter
f
composeFilter :: (a -> a) -> m () Source
Composes your filter function with the existing filter function.
getFilter :: m b -> m (b, a -> a) Source
Retrieves the filter from the environment.
Monad m => FilterMonad Response (WebT m) | |
Monad m => FilterMonad Response (ServerPartT m) | |
FilterMonad a m => FilterMonad a (ExceptT e m) | |
(Error e, FilterMonad a m) => FilterMonad a (ErrorT e m) | |
(FilterMonad res m, Monoid w) => FilterMonad res (WriterT w m) | |
(FilterMonad res m, Monoid w) => FilterMonad res (WriterT w m) | |
FilterMonad res m => FilterMonad res (StateT s m) | |
FilterMonad res m => FilterMonad res (StateT s m) | |
FilterMonad res m => FilterMonad res (ReaderT r m) | |
Monad m => FilterMonad a (FilterT a m) | |
(FilterMonad res m, Monoid w) => FilterMonad res (RWST r w s m) | |
(FilterMonad res m, Monoid w) => FilterMonad res (RWST r w s m) |
ignoreFilters :: FilterMonad a m => m () Source
The basic Response
building object.
MonadTrans WebT | |
MonadTransControl WebT | |
MonadBase b m => MonadBase b (WebT m) | |
MonadBaseControl b m => MonadBaseControl b (WebT m) | |
MonadError e m => MonadError e (WebT m) | |
MonadReader r m => MonadReader r (WebT m) | |
MonadState st m => MonadState st (WebT m) | |
MonadWriter w m => MonadWriter w (WebT m) | |
Monad m => WebMonad Response (WebT m) | |
Monad m => FilterMonad Response (WebT m) | |
(Functor m, MonadPlus m) => Alternative (WebT m) | |
Monad m => Monad (WebT m) | |
Functor m => Functor (WebT m) | |
(Monad m, MonadPlus m) => MonadPlus (WebT m) | |
(Monad m, Functor m) => Applicative (WebT m) | |
MonadThrow m => MonadThrow (WebT m) | |
MonadCatch m => MonadCatch (WebT m) | |
MonadIO m => MonadIO (WebT m) | |
(Monad m, MonadPlus m) => Monoid (WebT m a) | |
type StT WebT a = StT MaybeT (StT (FilterT Response) (StT (ErrorT Response) a)) | |
type StM (WebT m) a = ComposeSt WebT m a |
type UnWebT m a = m (Maybe (Either Response a, FilterFun Response)) Source
UnWebT
is almost exclusively used with mapServerPartT
. If you
are not using mapServerPartT
then you do not need to wrap your
head around this type. If you are -- the type is not as complex as
it first appears.
It is worth discussing the unpacked structure of WebT
a bit as
it's exposed in mapServerPartT
and mapWebT
.
A fully unpacked WebT
has a structure that looks like:
ununWebT $ WebT m a :: m (Maybe (Either Response a, FilterFun Response))
So, ignoring m
, as it is just the containing Monad
, the
outermost layer is a Maybe
. This is Nothing
if mzero
was
called or
if Just
(Either
Response
a, SetAppend
(Endo
Response
))mzero
wasn't called. Inside the Maybe
, there
is a pair. The second element of the pair is our filter function
. FilterFun
Response
is a type
alias for FilterFun
Response
. This is
just a wrapper for a SetAppend
(Dual
(Endo
Response
))
function with a
particular Response
-> Response
Monoid
behavior. The value
Append (Dual (Endo f))
Causes f
to be composed with the previous filter.
Set (Dual (Endo f))
Causes f
to not be composed with the previous filter.
Finally, the first element of the pair is either
or Left
Response
.Right
a
Another way of looking at all these pieces is from the behaviors
they control. The Maybe
controls the mzero
behavior.
comes from the Set
(Endo
f)setFilter
behavior. Likewise,
is from Append
(Endo
f)composeFilter
.
is what you get when you call Left
Response
finishWith
and
is the normal exit.Right
a
An example case statement looks like:
ex1 webt = do val <- ununWebT webt case val of Nothing -> Nothing -- this is the interior value when mzero was used Just (Left r, f) -> Just (Left r, f) -- r is the value that was passed into "finishWith" -- f is our filter function Just (Right a, f) -> Just (Right a, f) -- a is our normal monadic value -- f is still our filter function
class Monad m => WebMonad a m | m -> a where Source
WebMonad
provides a means to end the current computation
and return a Response
immediately. This provides an
alternate escape route. In particular it has a monadic value
of any type. And unless you call
first your
response filters will be applied normally.setFilter
id
Extremely useful when you're deep inside a monad and decide
that you want to return a completely different content type,
since it doesn't force you to convert all your return types to
Response
early just to accommodate this.
:: a | value to return (For |
-> m b |
Monad m => WebMonad Response (WebT m) | |
Monad m => WebMonad Response (ServerPartT m) | |
WebMonad a m => WebMonad a (ExceptT e m) | |
(Error e, WebMonad a m) => WebMonad a (ErrorT e m) | |
(WebMonad a m, Monoid w) => WebMonad a (WriterT w m) | |
(WebMonad a m, Monoid w) => WebMonad a (WriterT w m) | |
WebMonad a m => WebMonad a (StateT s m) | |
WebMonad a m => WebMonad a (StateT s m) | |
WebMonad a m => WebMonad a (ReaderT r m) | |
(WebMonad a m, Monoid w) => WebMonad a (RWST r w s m) | |
(WebMonad a m, Monoid w) => WebMonad a (RWST r w s m) |
escape :: (WebMonad a m, FilterMonad a m) => m a -> m b Source
Used to ignore all your filters and immediately end the
computation. A combination of ignoreFilters
and finishWith
.
escape' :: (WebMonad a m, FilterMonad a m) => a -> m b Source
An alternate form of escape
that can be easily used within a do
block.
mapWebT :: (UnWebT m a -> UnWebT n b) -> WebT m a -> WebT n b Source
See mapServerPartT
for a discussion of this function.
localContext :: Monad m => (WebT m a -> WebT m' a) -> ServerPartT m a -> ServerPartT m' a Source
This is kinda like a very oddly shaped mapServerPartT
or mapWebT
.
You probably want one or the other of those.
multi :: (Monad m, MonadPlus m) => [ServerPartT m a] -> ServerPartT m a Source
Deprecated: Use msum instead
Deprecated: use msum
.
debugFilter :: (MonadIO m, Show a) => ServerPartT m a -> ServerPartT m a Source
Deprecated: This function appears to do nothing.
What is this for, exactly? I don't understand why Show a
is
even in the context Deprecated: This function appears to do nothing
at all. If it use it, let us know why.
outputTraceMessage :: String -> a -> a Source
mkFailMessage :: (FilterMonad Response m, WebMonad Response m) => String -> m b Source
failResponse :: String -> Response Source
escapeString :: String -> String Source