-- 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.9.3
-- | 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] :: (IsAcidic st, SafeCopy st, Typeable st) => 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 :: forall event m. (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 :: forall event m. (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
-- | Left-associative fold operation for constructor applications.
--
-- The type of gfoldl is a headache, but operationally it is a
-- simple generalisation of a list fold.
--
-- The default definition for gfoldl is const
-- id, which is suitable for abstract datatypes with no
-- substructures.
gfoldl :: Data a => (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. () => g -> c g) -> a -> c a
-- | Unfolding constructor applications
gunfold :: Data a => (forall b r. Data b => c (b -> r) -> c r) -> (forall r. () => r -> c r) -> Constr -> c a
-- | Obtaining the constructor from a given datum. For proper terms, this
-- is meant to be the top-level constructor. Primitive datatypes are here
-- viewed as potentially infinite sets of values (i.e., constructors).
toConstr :: Data a => a -> Constr
-- | The outer type constructor of the type
dataTypeOf :: Data a => a -> DataType
-- | Mediate types and unary type constructors.
--
-- In Data instances of the form
--
--
-- instance (Data a, ...) => Data (T a)
--
--
-- dataCast1 should be defined as gcast1.
--
-- The default definition is const Nothing, which
-- is appropriate for instances of other forms.
dataCast1 :: (Data a, Typeable t) => (forall d. Data d => c (t d)) -> Maybe (c a)
-- | Mediate types and binary type constructors.
--
-- In Data instances of the form
--
--
-- instance (Data a, Data b, ...) => Data (T a b)
--
--
-- dataCast2 should be defined as gcast2.
--
-- The default definition is const Nothing, which
-- is appropriate for instances of other forms.
dataCast2 :: (Data a, Typeable t) => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a)
-- | A generic transformation that maps over the immediate subterms
--
-- The default definition instantiates the type constructor c in
-- the type of gfoldl to an identity datatype constructor, using
-- the isomorphism pair as injection and projection.
gmapT :: Data a => (forall b. Data b => b -> b) -> a -> a
-- | A generic query with a left-associative binary operator
gmapQl :: Data a => (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r
-- | A generic query with a right-associative binary operator
gmapQr :: forall r r'. Data a => (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r
-- | A generic query that processes the immediate subterms and returns a
-- list of results. The list is given in the same order as originally
-- specified in the declaration of the data constructors.
gmapQ :: Data a => (forall d. Data d => d -> u) -> a -> [u]
-- | A generic query that processes one child by index (zero-based)
gmapQi :: Data a => Int -> (forall d. Data d => d -> u) -> a -> u
-- | A generic monadic transformation that maps over the immediate subterms
--
-- The default definition instantiates the type constructor c in
-- the type of gfoldl to the monad datatype constructor, defining
-- injection and projection using return and >>=.
gmapM :: (Data a, Monad m) => (forall d. Data d => d -> m d) -> a -> m a
-- | Transformation of at least one immediate subterm does not fail
gmapMp :: (Data a, MonadPlus m) => (forall d. Data d => d -> m d) -> a -> m a
-- | Transformation of one immediate subterm with success
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 :: k)
-- | Create an AcidState given a log directory and an initial value.
--
-- This will create or resume a log found in directory. Running
-- two AcidState's from the same directory is an error but will not
-- result in dataloss.
openLocalStateFrom :: (IsAcidic st, SafeCopy st) => FilePath -> st -> IO (AcidState st)
-- | Create an AcidState given an initial value.
--
-- This will create or resume a log found in the "state/[typeOf state]/"
-- directory.
openLocalState :: (Typeable st, IsAcidic st, SafeCopy st) => st -> IO (AcidState st)
-- | Create the control structures required for acid states using Template
-- Haskell.
--
-- This code:
--
--
-- myUpdate :: Argument -> Update State Result
-- myUpdate arg = ...
--
-- myQuery :: Argument -> Query State Result
-- myQuery arg = ...
--
-- $(makeAcidic ''State ['myUpdate, 'myQuery])
--
--
-- will make State an instance of IsAcidic and provide
-- the following events:
--
--
-- data MyUpdate = MyUpdate Argument
-- data MyQuery = MyQuery Argument
--
makeAcidic :: Name -> [Name] -> Q [Dec]
-- | State container offering full ACID (Atomicity, Consistency, Isolation
-- and Durability) guarantees.
--
--
-- - Atomicity State changes are all-or-nothing. This
-- is what you'd expect of any state variable in Haskell and AcidState
-- doesn't change that.
-- - Consistency No event or set of events will break
-- your data invariants.
-- - Isolation Transactions cannot interfere with each
-- other even when issued in parallel.
-- - Durability Successful transaction are guaranteed
-- to survive unexpected system shutdowns (both those caused by hardware
-- and software).
--
data AcidState st
-- | Run a query in the Update Monad.
liftQuery :: Query st a -> Update st a
class IsAcidic st
-- | Context monad for Update events.
data Update st a
-- | Context monad for Query events.
data Query st a
-- | Events return the same thing as Methods. The exact type of
-- EventResult depends on the event.
type EventResult ev = MethodResult ev
type EventState ev = MethodState ev
-- | All UpdateEvents are also Methods.
class Method ev => UpdateEvent ev
-- | All QueryEvents are also Methods.
class Method ev => QueryEvent ev
-- | un-lift.
unXMLGenT :: XMLGenT m a -> m a
-- | The monad transformer that allows a monad to generate XML values.
newtype XMLGenT (m :: Type -> Type) a
XMLGenT :: m a -> XMLGenT (m :: Type -> Type) a
data family AttributeType (m :: Type -> Type)
data family ChildType (m :: Type -> Type)
type family StringType (m :: Type -> Type)
type family XMLType (m :: Type -> Type)
-- | Generate XML values in some XMLGenerator monad.
class Monad m => XMLGen (m :: Type -> Type) where {
type family XMLType (m :: Type -> Type);
type family StringType (m :: Type -> Type);
data family ChildType (m :: Type -> Type);
data family AttributeType (m :: Type -> Type);
}
genElement :: XMLGen m => Name (StringType m) -> [XMLGenT m [AttributeType m]] -> [XMLGenT m [ChildType m]] -> XMLGenT m (XMLType m)
genEElement :: XMLGen m => Name (StringType m) -> [XMLGenT m [AttributeType m]] -> XMLGenT m (XMLType m)
xmlToChild :: XMLGen m => XMLType m -> ChildType m
pcdataToChild :: XMLGen m => StringType m -> ChildType m
-- | Embed values as child nodes of an XML element. The parent type will be
-- clear from the context so it is not mentioned.
class XMLGen m => EmbedAsChild (m :: Type -> Type) c
asChild :: EmbedAsChild m c => c -> GenChildList m
data Attr n a
(:=) :: n -> a -> Attr n a
-- | Similarly embed values as attributes of an XML element.
class XMLGen m => EmbedAsAttr (m :: Type -> Type) a
asAttr :: EmbedAsAttr m a => a -> GenAttributeList m
class (XMLGen m, SetAttr m XMLType m, AppendChild m XMLType m, EmbedAsChild m XMLType m, EmbedAsChild m [XMLType m], EmbedAsChild m Text, EmbedAsChild m Char, EmbedAsChild m (), EmbedAsAttr m Attr Text Text, EmbedAsAttr m Attr Text Int, EmbedAsAttr m Attr Text Bool) => XMLGenerator (m :: Type -> Type)
fromStringLit :: String -> Text
-- | The XML datatype representation. Is either an Element or CDATA.
data XML
-- | an error type used with reform forms
data AppError
AppCFE :: CommonFormError [Input] -> AppError
TextError :: Text -> AppError
instance Data.String.IsString Happstack.Foundation.AppError
instance Text.Reform.Backend.FormError Happstack.Foundation.AppError
instance (GHC.Base.Functor m, GHC.Base.Monad m) => HSP.XMLGenerator.EmbedAsChild (Happstack.Foundation.FoundationT' url acidState requestState m) Happstack.Foundation.AppError
instance (GHC.Base.Functor m, GHC.Base.Monad m) => Happstack.Foundation.HasAcidState (Happstack.Foundation.FoundationT url (Data.Acid.Abstract.AcidState acidState) requestState m) acidState
instance Happstack.Foundation.HasAcidState (Happstack.Foundation.FoundationT' url acid reqSt m) acidSt => Happstack.Foundation.HasAcidState (HSP.XMLGenerator.XMLGenT (Happstack.Foundation.FoundationT' url acid reqSt m)) acidSt