-- 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: -- -- -- -- 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 -- -- -- -- 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. -- -- 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