
 <p>Anyway, on to the code. We are going to implement a simple hit
 counter application. First we just enable a bunch of language
 extensions that happstack-state requires, and import a bunch of
 modules.</p>

> {-# LANGUAGE GeneralizedNewtypeDeriving, ImpredicativeTypes, TemplateHaskell, 
>   FlexibleInstances, FlexibleContexts, MultiParamTypeClasses, UndecidableInstances, 
>   DeriveDataTypeable, TypeFamilies, RankNTypes, TypeSynonymInstances #-}
> module Main where

> import Control.Concurrent (forkIO)
> import Control.Monad.State (MonadState(get,put))
> import qualified Data.ByteString as S
> import qualified Data.ByteString.Char8 as C (pack, unpack)
> import Happstack.Data (Default(defaultValue),deriveAll)
> import Happstack.State (Component(..),Proxy(..), Version(..),End, createCheckpoint, 
>                         deriveSerialize, mkMethods, shutdownSystem, startSystemState, 
>                         update, waitForTermination)
> import Happstack.Server.Cron (cron)
> import Hyena.Server (serve)
> import Network.Wai (Application, Enumerator)
>
> -- * State

 <p>Next we implement a happstack-state component which stores the
 number of requests we have received. This code is in no way hyena
 specific.</p>

 <p>First we declare a simple type for counting requests.</p>

>
> $(deriveAll [''Read, ''Show, ''Eq ,''Ord, ''Default, ''Num, ''Enum]
>  [d|
>      newtype Hits = Hits Integer
>   |])

  <p>Next we create <code>Serialize</code> and <code>Version</code>
 instances so that we can use the <code>Hits</code> type with
 <kbd>happstack-state</kbd>.</p>

> $(deriveSerialize ''Hits)
> instance Version Hits


  <p>Now we create a <code>Component</code> for the <code>Hits</code> type.</p>

> instance Component Hits where
>    type Dependencies Hits = End
>    initialValue = defaultValue


  <p>Then we create a simple function which increments the number of
 hits, and returns to use the current (updated) count.</p>

> inc :: (MonadState Hits m) => m Hits
> inc =
>     do hits <- get
>        let hits' = succ hits
>        put hits'
>        return hits'

 <p>And, then we turn the function into a method that can be used with
 <code>update</code>.</p>

> $(mkMethods ''Hits ['inc])


> -- * main

  <p>Next we move onto the main function. This main function is almost
 exactly what we would have for a <kbd>happstack-server</kbd> based
 program, except the traditional <code>simpleHTTP conf impl</code> is
 replaced with the <kbd>hyena</kbd> equivalent <code>server
 hitApplication</code>.</p>

> main :: IO ()
> main = 
>     do ctl <- startSystemState (Proxy :: Proxy Hits)
>        forkIO $ cron (60*60*24) (createCheckpoint ctl)
>        forkIO $ serve hitApplication
>        putStrLn "running..."
>        waitForTermination
>        createCheckpoint ctl
>        shutdownSystem ctl

 <p>An <code>Application</code> is a 4-tuple which consists of an HTTP
 return code (200, 404, etc), a string associated with that return
 code (OK, Not Found, etc), a list of HTTP headers, and an enumerator
 which generates the body of the HTTP response.</p>

> hitApplication :: Application
> hitApplication environ = do
>   return (200, C.pack "OK", [textPlain, closeC], showHits)

 <p>There are two important headers set for the hit application. The
 first is simply the <code>Content-type: text/plain</code> header.</p>

> textPlain :: (S.ByteString, S.ByteString)
> textPlain = (C.pack "Content-type", C.pack "text/plain")

  <p>The second header is <code>Connection: close</code>. This tells
 hyena that it should close the connection after the enumerator has
 finished outputting the body. This is required because HTTP 1.1
 specifies that all HTTP connections are 'keep-alive' by default.</p>

> closeC :: (S.ByteString, S.ByteString)
> closeC = (C.pack "Connection", C.pack "close")

 <p>There are three ways that an HTTP connection can be closed:</p>

  <ol>
   <li>The HTTP server sets the <code>Content-length</code> header and
    the client closes the connection after downloading the specified
     number of bytes.</li>

   <li>The HTTP server sets the <code>Connection: close</code> header
       in the Response and then closes the connection after it sends
 the body.</li>

   <li>The client sets the <code>Connection: close</code> header in
 the Request. The server notes this and closes the connection after
 sending the body.</li>
   </ol>

 <p>All three of these methods work in hyena. If none of the above
 conditions are met, then hyena assumes that you don't want the
 connection closed.</p>

 <p>Finally we have our <code>Enumerator</code> which generates the
 HTTP response body:</p>

> showHits :: Enumerator
> showHits =
>     let yieldHits f z = do
>           hits <- update Inc
>           z' <- f z (C.pack $ "hello, you are visitor number: " ++ show hits ++ "\n")
>           case z' of
>             (Left z'') -> return z''
>             (Right z'') -> return z''
>     in
>       yieldHits

 <p>This <code>Enumerator</code> is very boring. It outputs one line
 of text, and then it is done. It is not a particular instructive
 example of an <code>Enumerator</code>, so rather than trying to
 understand it now, I recommend moving on to the next section where we
 will examine <code>Enumerators</code> using more instructive examples.</p>