[view users/logged in as works. work on tutorialOA text thomashartman1@gmail.com**20080623183230] hunk ./src/Controller.hs 15 + hunk ./src/Controller.hs 19 -impl :: [ServerPartT IO Response] -impl = debugFilter $ +controller :: [ServerPartT IO Response] +controller = debugFilter $ hunk ./src/Controller.hs 27 - , exactdir "view" [withDataFn (liftM Just (readCookieValue "sid") `mplus` return Nothing) viewPage] - , exactdir "list" userListPage ] + , dir "view" [withDataFn (liftM Just (readCookieValue "sid") `mplus` return Nothing) viewPage] + , dir "list" userListPage ] hunk ./src/Main.hs 5 - -import Control.Monad hunk ./src/Main.hs 6 -import Text.StringTemplate - -import Misc hunk ./src/Main.hs 7 -import View hunk ./src/Main.hs 8 +import Misc hunk ./src/Main.hs 11 - let p = 5001 - control <- startSystemState entryPoint + let p = 5001 + startSystemState entryPoint -- start the HAppS state system hunk ./src/Main.hs 14 - simpleHTTP (Conf {port=p}) impl + simpleHTTP (Conf {port=p}) controller -- start serving web pages hunk ./src/Misc.hs 4 -import HAppS.Server +import HAppS.Server hunk ./templates/header.st 21 + |Logged in as + |View all users hunk ./templates/main-function.st 1 -asdf +
Have a look at main function at the core of this web application.
+ +Two bits of code that should jump out at you as being important are "entrypoint" and "controller".
+ +So, open this file in ghci: cd src; ghci Main.hs and have a look at these functions using ghci :i .
+ +*Main> :info entryPoint
+
entryPoint :: HAppS.Data.Proxy.Proxy Session.State
+
-- Defined at Model.hs:21:0-9
+
*Main> :i controller
+
controller :: [ServerPartT IO Response]
+
-- Defined at Controller.hs:20:0-9
+
The entrypoint function has to do with the HAppS state system, and we'll pospone learning about it for later.
+ +The controller function is a list of ServerPartTs, which are basically handlers that +accept an HTTP request and return a response.
+ +Now you have a choice about what to read next.
+ +If you are in a hurry to write a HAppS application without delving too much into what's going on behind the scenes, +read basic url handling, which looks at what's happening in the controller code.
+ +If you want to understand the HAppS type system in more detail, read understanding HAppS types. +
+ + + addfile ./templates/understanding-happs-types.st hunk ./templates/understanding-happs-types.st 1 + +I find it helpful to have ghci tell me about the types in the code I am reading. Here is a snip of ghci output.
+ +
+
*Main>:i simpleHTTP
+
simpleHTTP :: (ToMessage a) => Conf -> [ServerPartT IO a] -> IO ()
+
-- Defined in HAppS.Server.SimpleHTTP
+
*Main>:i Conf
+
data Conf = Conf {port :: Int}
+
-- Defined in HAppS.Server.HTTP.Types
+
*Main> :i ServerPartT
+
newtype ServerPartT m a
+
= ServerPartT {unServerPartT :: Request -> WebT m a}
+
-- Defined in HAppS.Server.SimpleHTTP
+
instance [overlap ok] (Monad m) => Monad (ServerPartT m)
+
-- Defined in HAppS.Server.SimpleHTTP
+
*Main> :i WebT
+
newtype WebT m a = WebT {unWebT :: m (Result a)}
+
-- Defined in HAppS.Server.SimpleHTTP
+
instance [overlap ok] (Monad m) => Monad (WebT m)
+
-- Defined in HAppS.Server.SimpleHTTP
+
So basically what this tells you is that the meat of a HAppS application is a list of ServerParts, which themselves are a wrapper over a function that takes an HTTP request to a response.
+ +I use ghci info a lot, and you should too as you are learning HAppS. This kind of comfort with the HAppS type system is particularly important at the present time, when the HAppS documentation is relatively sparse
+ +... also read read TK happs-tutorial2 for a more in-depth look at HAppS and the HAppS type system.