
On Tue, Jan 25, 2011 at 8:35 PM, Jeremy Shaw
On Jan 25, 2011, at 12:10 PM, Michael Snoyman wrote:
7. the ServerPartT monad has a built-in FilterT monad which makes it easy to apply a function (Response -> Response) to modify the response.
In all honesty, this is an argument *against* frameworks, not for them: at a WAI level, we don't need a FilterT monad, since an application is just a function.
(And I can't believe I'm giving arguments against frameworks here, I obviously think they're a good thing. I'm just trying to be fair.)
Sure, you can do everything at the low-level. The idea is to add value. Ultimately happstack calls this function,
simpleHTTP'' :: (ToMessage b, Monad m, Functor m) => ServerPartT m b -> Request -> m Response
which is basically a function to convert a ServerPartT into a WAI-like, type Application = Request -> IO Response. :)
The value added by the FilterT monad is that it allows you to apply a transformation to the Response before you actually have created the Response.
For example, I may have a function that adds a session cookie. But I don't have to structure my code so that the function is run after I have generated the response. For example, lets say I have a function that sets a cookie and returns the response body as HTML:
myPart :: ServerPart Html myPart = do addCookie someCookie return $ <html>...</html>
I can't add the cookie directly to the Response yet, because this function returns Html not a Response. The cookie is added later after the Html is converted to a Response.
I assume the WriterT (Endo [Header]) thing in yesod serves a similar purpose ?
Yes, precisely. As I see it, the difference between the two approaches would be: * Yesod's is a little bit faster. And I mean a *little* bit. * Happstack's is more powerful, in that you can do more than simply append a header. Would you concur? Michael