{"id":238,"date":"2009-01-11T00:21:52","date_gmt":"2009-01-10T23:21:52","guid":{"rendered":"http:\/\/www.nobugs.org\/blog\/?p=238"},"modified":"2009-01-11T00:23:38","modified_gmt":"2009-01-10T23:23:38","slug":"hacking-with-happs-what-type-handler","status":"publish","type":"post","link":"https:\/\/www.nobugs.org\/blog\/archives\/2009\/01\/11\/hacking-with-happs-what-type-handler\/","title":{"rendered":"Hacking with HAppS &#8211; what type, handler?"},"content":{"rendered":"<p>(These posts are prettified versions of my notes that I made whilst stumbling around HAppS for the first time.  I hope they&#8217;ll be of use to future HAppS explorers!)<\/p>\n<p><em>Note 1 .. In which we figure out what ServerPartT and WebT really are.<\/em><\/p>\n<p>When we start HAppS running with ..<\/p>\n<pre lang=\"haskell\">\r\n   simpleHTTP config list_of_handlers :: IO ()\r\n<\/pre>\n<p>&#8230; what type do the handlers have?  Let&#8217;s explore some possible universes!<\/p>\n<p>In a simple world, a handler could have type<\/p>\n<pre lang=\"haskell\">\r\n    Request -> Maybe Response\r\n<\/pre>\n<p>This allows handlers to be selective about which Requests they handle, which is useful.  But it also means that handlers must be pure functions so there&#8217;d be no way of maintaining any &#8216;application state&#8217; between requests.  Not very useful!<\/p>\n<p>Let&#8217;s try to remedy that.  If the handlers had type:<\/p>\n<pre lang=\"haskell\">\r\n   Request -> State S Response\r\n<\/pre>\n<p>.. then we&#8217;d be able to retain and modify some application state (of type S) between handler invocations.  But that&#8217;s all we&#8217;d be able to do.  We still couldn&#8217;t write logs to disk, read file contents or talk to databases.<\/p>\n<p>To allow handlers to do that, handlers would need to have type ..<\/p>\n<pre lang=\"haskell\">\r\n  Request -> IO Response\r\n<\/pre>\n<p>(As an aside, note that whilst simpleHTTP has type &#8220;IO ()&#8221; it&#8217;s up to simpleHTTP whether or not it exposes the full power of the IO monad to the handlers.  However, as we&#8217;ve just seen, not doing so would pretty much cripple the handlers)<\/p>\n<p>So is this really what HAppS gives you?  Let&#8217;s see.  In the real world HAppS handlers have type &#8220;ServerPartT IO a&#8221; which is defined to be &#8230;<\/p>\n<pre lang=\"haskell\">\r\nnewtype ServerPartT m a = ServerPartT { unServerPartT :: Request -> WebT m a }\r\n<\/pre>\n<p>In other words, if you have a value of type &#8220;Request -> WebT m a&#8221;, you can tag it with the ServerPartT constructor to say &#8220;this ain&#8217;t just any function of that type, it&#8217;s part of a web server, dogammit!&#8221;.<\/p>\n<p>But, apart from the tag, our handlers really just have type &#8220;Request -> WebT m a&#8221;.  So what&#8217;s a WebT?<\/p>\n<pre lang=\"haskell\">\r\nnewtype WebT m a = WebT { unWebT :: m (Result a) }\r\n<\/pre>\n<p>So, ignoring the tag, it looks kinda like our handlers can produce <em>any<\/em> monadic computation that, when run, yields a &#8220;Result a&#8221; (the &#8220;Result a&#8221; type lets us say &#8220;I handled this request, here&#8217;s my answer&#8221; or &#8220;I didn&#8217;t handle this request&#8221;)<\/p>\n<p>Hmm, there&#8217;s something not right there.  If that was the case, it would be possible to use, for example, both &#8220;Result -> IO (Result a)&#8221; and &#8220;Result -> State S (Result a)&#8221; as handlers.  But how would simpleHTTP &#8216;run&#8217; such monadic computations?  To run a State computation you use &#8220;evalState&#8221;.  To run an IO computation, you have to return it from main.  There&#8217;s no single way to run all possible monads.<\/p>\n<p>Did I miss something?  Yes, sort of &#8211; I just blindly assumed &#8216;m&#8217; was a monad because of the way it was used.  But there&#8217;s no &#8220;Monad m =>&#8221; constraints anywhere.  And, in fact, if we go back to the start ..<\/p>\n<pre lang=\"haskell\">\r\nsimpleHTTP :: ToMessage a => Conf -> [ServerPartT IO a] -> IO ()\r\n<\/pre>\n<p>.. we can see that, right from the top, simpleHTTP only deals with ServerPartT&#8217;s and WebT&#8217;s where the &#8216;m&#8217; type parameter is IO.<\/p>\n<p>So, after all that, the handlers in HAppS handlers can be anything of type: Request -> IO (Response a).  The &#8216;a&#8217; type needs to be something that HApps can figure out a content-type and be able to make an HTTP message from (the ToMessage type class).  The &#8220;IO (Response a)&#8221; part gets dressed up as a &#8220;WebT&#8221; (think: computation that produces the response).  And the whole thing things gets dressed up as a &#8220;ServerPartT&#8221; (think: request handler).  <\/p>\n<p>What does each bit do?  The IO part gives you free reign to do side-effecting computations, which get sequentially executed by the runtime.  The Response part allows you to say &#8216;I handled this&#8217; or &#8216;didn&#8217;t handle it&#8217; and the &#8216;a&#8217; part can be your XML or HTML data type (so long as its an instance of ToMessage).<\/p>\n<p>So that&#8217;s it.  <\/p>\n<p>Man, that was a lot of complexity for such a simple end result.  I don&#8217;t understand why there&#8217;s so much generality in the types of ServerT and WebT &#8211;  I&#8217;d love to know!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>(These posts are prettified versions of my notes that I made whilst stumbling around HAppS for the first time. I hope they&#8217;ll be of use to future HAppS explorers!) Note 1 .. In which we figure out what ServerPartT and WebT really are. When we start HAppS running with .. simpleHTTP config list_of_handlers :: IO [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[30,9],"class_list":["post-238","post","type-post","status-publish","format-standard","hentry","category-general","tag-happs","tag-haskell"],"_links":{"self":[{"href":"https:\/\/www.nobugs.org\/blog\/wp-json\/wp\/v2\/posts\/238","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.nobugs.org\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.nobugs.org\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.nobugs.org\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.nobugs.org\/blog\/wp-json\/wp\/v2\/comments?post=238"}],"version-history":[{"count":12,"href":"https:\/\/www.nobugs.org\/blog\/wp-json\/wp\/v2\/posts\/238\/revisions"}],"predecessor-version":[{"id":250,"href":"https:\/\/www.nobugs.org\/blog\/wp-json\/wp\/v2\/posts\/238\/revisions\/250"}],"wp:attachment":[{"href":"https:\/\/www.nobugs.org\/blog\/wp-json\/wp\/v2\/media?parent=238"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.nobugs.org\/blog\/wp-json\/wp\/v2\/categories?post=238"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.nobugs.org\/blog\/wp-json\/wp\/v2\/tags?post=238"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}