-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/
-- | Glue code for using Happstack with acid-state, web-routes, reform, and HSP
--
-- happstack-foundation is a library which builds on top of existing
-- components to provide a powerful and type-safe environment for web
-- development. It uses:
--
-- happstack-server for the underlying HTTP support
--
-- HSP for HTML templates
--
-- web-routes for type-safe URL routing
--
-- reform for type-safe form generation and validation
--
-- acid-state for persistent data storage
@package happstack-foundation
@version 0.5.5
-- | happstack-foundation provides a type-safe environment for
-- Haskell web development. It builds on top of:
--
--
-- - happstack-server - an HTTP server
-- - HSP - HTML Templating
-- - web-routes - type-safe URL routing
-- - reform - type-safe form composition and validation
-- - acid-state - native Haskell persistent database
--
--
-- An example application can be found here:
--
--
-- http://patch-tag.com/r/mae/happstack/snapshot/current/content/pretty/happstack-foundation/examples/ControlV/Main.hs
--
-- A screencast can be found here:
--
-- http://www.youtube.com/watch?v=7Wmszk4wZxQ
--
-- happstack-foundation itself is not yet documented in the
-- Happstack Crash Course. However, all of the components that it uses
-- are:
--
-- http://www.happstack.com/docs/crashcourse/index.html
module Happstack.Foundation
-- | configuration information for our acid-state database
data AcidConfig st
AcidLocal :: Maybe FilePath -> st -> AcidConfig (AcidState st)
AcidUsing :: st -> AcidConfig st
-- | configuration for server
data FoundationConf
FoundationConf :: Conf -> BodyPolicy -> FoundationConf
httpConf :: FoundationConf -> Conf
bodyPolicy :: FoundationConf -> BodyPolicy
-- | configuration
defaultConf :: FoundationConf
-- | the FoundationT monad
--
--
-- - url - the type-safe URL route type
-- - acidState - the type of the state value stored in
-- acid-state
-- - requestState - a per-request state value that the
-- developer can getsetmodify
-- - m - inner monad
--
--
-- see also: whereami, getRequestState,
-- setRequestState, modifyRequestState, simpleApp
type FoundationT url acidState requestState m = XMLGenT (FoundationT' url acidState requestState m)
-- | similar to the FoundationT' type alias, but without the
-- XMLGenT wrapper. This variant is most often used in class
-- constraints.
type FoundationT' url acidState requestState m = RouteT url (StateT (AppState url acidState requestState) (ServerPartT m))
-- | FoundationForm is an alias for working with reform based Forms
type FoundationForm url acidState requestState m = Form (FoundationT url acidState requestState m) [Input] AppError [FoundationT url acidState requestState m XML] ()
-- | returns the decoded url from the Request
whereami :: (Functor m, Monad m) => FoundationT url acidState requestState m url
-- | get the requestState value
getRequestState :: (Functor m, MonadState (AppState url acidState requestState) m) => m requestState
-- | set the requestState value
setRequestState :: (Functor m, MonadState (AppState url acidState requestState) m) => requestState -> m ()
-- | set the requestState value
modifyRequestState :: MonadState (AppState url acidState requestState) m => (requestState -> requestState) -> m ()
-- | default page template
defaultTemplate :: (Functor m, Monad m, XMLGenerator (FoundationT' url acidState requestState m), EmbedAsChild (FoundationT' url acidState requestState m) body, EmbedAsChild (FoundationT' url acidState requestState m) headers, XMLType (FoundationT' url acidState requestState m) ~ XML) => Text -> headers -> body -> FoundationT url acidState requestState m XML
-- | HasAcidState provides a single method getAcidState which
-- can be used to retrieve an AcidState handle from the current
-- monad.
class HasAcidState m st
getAcidState :: HasAcidState m st => m (AcidState st)
-- | wrapper around query from acid-state
--
-- This variant automatically gets the AcidState handle from the
-- monad
query :: (Functor m, MonadIO m, QueryEvent event, HasAcidState m (EventState event)) => event -> m (EventResult event)
-- | wrapper around update from acid-state
--
-- This variant automatically gets the AcidState handle from the
-- monad
update :: (Functor m, MonadIO m, UpdateEvent event, HasAcidState m (EventState event)) => event -> m (EventResult event)
getAcidSt :: (Functor m, MonadState (AppState url acidState requestState) m) => m acidState
-- | run the application
--
-- starts the database, listens for requests, etc.
simpleApp :: (ToMessage a, PathInfo url, Monad m) => (forall r. m r -> IO r) -> FoundationConf -> AcidConfig acidState -> requestState -> url -> Text -> (url -> FoundationT url acidState requestState m a) -> IO ()
-- | The Data class comprehends a fundamental primitive
-- gfoldl for folding over constructor applications, say terms.
-- This primitive can be instantiated in several ways to map over the
-- immediate subterms of a term; see the gmap combinators later
-- in this class. Indeed, a generic programmer does not necessarily need
-- to use the ingenious gfoldl primitive but rather the intuitive
-- gmap combinators. The gfoldl primitive is completed by
-- means to query top-level constructors, to turn constructor
-- representations into proper terms, and to list all possible datatype
-- constructors. This completion allows us to serve generic programming
-- scenarios like read, show, equality, term generation.
--
-- The combinators gmapT, gmapQ, gmapM, etc are all
-- provided with default definitions in terms of gfoldl, leaving
-- open the opportunity to provide datatype-specific definitions. (The
-- inclusion of the gmap combinators as members of class
-- Data allows the programmer or the compiler to derive
-- specialised, and maybe more efficient code per datatype. Note:
-- gfoldl is more higher-order than the gmap combinators.
-- This is subject to ongoing benchmarking experiments. It might turn out
-- that the gmap combinators will be moved out of the class
-- Data.)
--
-- Conceptually, the definition of the gmap combinators in terms
-- of the primitive gfoldl requires the identification of the
-- gfoldl function arguments. Technically, we also need to
-- identify the type constructor c for the construction of the
-- result type from the folded term type.
--
-- In the definition of gmapQx combinators, we use
-- phantom type constructors for the c in the type of
-- gfoldl because the result type of a query does not involve the
-- (polymorphic) type of the term argument. In the definition of
-- gmapQl we simply use the plain constant type constructor
-- because gfoldl is left-associative anyway and so it is readily
-- suited to fold a left-associative binary operation over the immediate
-- subterms. In the definition of gmapQr, extra effort is needed. We use
-- a higher-order accumulation trick to mediate between left-associative
-- constructor application vs. right-associative binary operation (e.g.,
-- (:)). When the query is meant to compute a value of type
-- r, then the result type withing generic folding is r
-- -> r. So the result of folding is a function to which we
-- finally pass the right unit.
--
-- With the -XDeriveDataTypeable option, GHC can generate
-- instances of the Data class automatically. For example, given
-- the declaration
--
--
-- data T a b = C1 a b | C2 deriving (Typeable, Data)
--
--
-- GHC will generate an instance that is equivalent to
--
--
-- instance (Data a, Data b) => Data (T a b) where
-- gfoldl k z (C1 a b) = z C1 `k` a `k` b
-- gfoldl k z C2 = z C2
--
-- gunfold k z c = case constrIndex c of
-- 1 -> k (k (z C1))
-- 2 -> z C2
--
-- toConstr (C1 _ _) = con_C1
-- toConstr C2 = con_C2
--
-- dataTypeOf _ = ty_T
--
-- con_C1 = mkConstr ty_T "C1" [] Prefix
-- con_C2 = mkConstr ty_T "C2" [] Prefix
-- ty_T = mkDataType "Module.T" [con_C1, con_C2]
--
--
-- This is suitable for datatypes that are exported transparently.
class Typeable a => Data a
gfoldl :: Data a => (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> a -> c a
gunfold :: Data a => (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c a
toConstr :: Data a => a -> Constr
dataTypeOf :: Data a => a -> DataType
dataCast1 :: (Data a, Typeable1 t) => (forall d. Data d => c (t d)) -> Maybe (c a)
dataCast2 :: (Data a, Typeable2 t) => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a)
gmapT :: Data a => (forall b. Data b => b -> b) -> a -> a
gmapQl :: Data a => (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r
gmapQr :: Data a => (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r
gmapQ :: Data a => (forall d. Data d => d -> u) -> a -> [u]
gmapQi :: Data a => Int -> (forall d. Data d => d -> u) -> a -> u
gmapM :: (Data a, Monad m) => (forall d. Data d => d -> m d) -> a -> m a
gmapMp :: (Data a, MonadPlus m) => (forall d. Data d => d -> m d) -> a -> m a
gmapMo :: (Data a, MonadPlus m) => (forall d. Data d => d -> m d) -> a -> m a
-- | The class Typeable allows a concrete representation of a type
-- to be calculated.
class Typeable a
typeOf :: Typeable a => a -> TypeRep
instance (Functor m, Monad m) => EmbedAsChild (FoundationT' url acidState requestState m) AppError
instance FormError AppError
instance IsString AppError
instance (Functor m, Monad m) => HasAcidState (FoundationT url (AcidState acidState) requestState m) acidState
instance HasAcidState (FoundationT' url acid reqSt m) acidSt => HasAcidState (XMLGenT (FoundationT' url acid reqSt m)) acidSt