--- Log opened Thu Jan 07 00:00:22 2010 00:00 < aep> i'm totally failing to understand the STateT example. should i be fluent in haskell before hacking with happs? i hoped to learn haskell with a paractical aproach 00:11 < mightybyte> aep: happstack isn't exactly the best thing to start with as a haskell novice. 00:11 < aep> right. thanks 00:11 < mightybyte> aep: But it's not necessary to know a ton of Haskell. 00:12 < mightybyte> aep: I had been playing around with haskell a little for maybe 6 months before I started learning happstack. 00:12 < aep> uh 00:13 < aep> well all i know is IO :/ 00:13 < mightybyte> I'd suggest that you start reading Real World Haskell first. 00:13 < mightybyte> ...or some of the other Haskell tutorials on the web. 00:14 < aep> yeah i tried. thats rather hard 00:15 < mightybyte> Yeah, Haskell is certainly a harder language than most. 00:15 < mightybyte> But that's what makes it so beneficial to learn. 00:17 < aep> actually i am impressed by the side effect free thing 00:17 < mightybyte> yeah 00:17 < aep> sounds like something you'd want long running code to be in 00:18 < mightybyte> After doing a good bit of multithreaded programming in Java, I found myself wishing for better ways to enforce purity. 00:18 < aep> umm java.. 00:18 < aep> java was my first garbage collected language. after that i didnt touch any GC lang in years 00:19 < aep> stability my ass... 00:19 < mightybyte> lol 00:19 < aep> i'm working on mission critical http servers, thats what dragged my interest to happs. 00:20 < aep> its all C right now. very stable. But it takes a while until you get there. long development cycle to find the minor quirks 00:21 < mightybyte> I had pretty good luck with Java. But around the time of Java 5 and 6. 00:21 < aep> haskell makes me feel comfortable in a way that one part cannot possibly have any implicit global effect 00:21 < mightybyte> Well, I've had pretty good luck with happstack. 00:22 < mightybyte> Although not without some hurdles along the way. 00:23 < mightybyte> But I think it's quite reasonable to expect that once a mature haskell web framework emerges it will be pretty good in the reliability department and have better performance than languages like Ruby, PHP, and Python 00:23 < aep> that too. compiled high level language = win 00:23 < mightybyte> Yep 00:24 < mightybyte> But if you can get through chapter 15 in Real World Haskell, you'll have a much better foundation to understand happstack. 00:25 < mightybyte> (And you might be able to skip some of the earlier chapters) 00:25 < aep> i got to 3 or 4 00:25 < aep> where he started skipping so much details that i got lost 00:25 < mightybyte> Definitely get through 4 00:25 < mightybyte> Might be able to skip 5 00:25 < mightybyte> Don't skip 6 though 00:26 < mightybyte> Then I'd say maybe chapters 7,9,13,14, and 15 00:26 < aep> do you think i should get the theoretical background first? 00:27 < aep> i quit university before category theory 00:27 < mightybyte> I don't think that level of theory is necessary. 00:27 < mightybyte> Can't hurt though. 00:27 < mightybyte> I haven't taken category theory. 00:28 < mightybyte> I did get set theory and group theory though. 00:28 < aep> aye thanks 00:28 < aep> yeah i think i had that too 00:28 < aep> although i didnt get it 00:29 < mightybyte> I didn't get much in the way of practical applications for it. 00:29 < mightybyte> You should have at least a basic idea of monads though because happstack uses them. 00:29 < aep> that's exactly where i struggled 00:29 < mightybyte> For me, the best way to get that was to just use them. 00:30 < aep> thats circular 00:30 < mightybyte> At first it's a huge fight, but things will gradually start to make sense. 00:30 < aep> have a clue before use them. get a clue by using them 00:30 < mightybyte> Yep 00:30 < aep> haha 00:30 < aep> that's EXACTLY the part where i am stuck 00:30 < mightybyte> I had read several monad tutorials before happstack. 00:30 < aep> hence my guess that it requires math 00:30 < mightybyte> I don't think so. 00:30 < aep> i used IO. but thats trivial 00:31 < mightybyte> Yeah. 00:31 < mightybyte> A monad is a container that gives you a programmable ';' 00:31 < aep> do you have any links of those tutorials you read? 00:31 < mightybyte> (to use a C programming analogy) 00:31 < mightybyte> Not off-hand. 00:32 < aep> a ';' ? 00:32 < aep> an end of command terminator? heh 00:32 < mightybyte> Yeah. In C, a ';' is a statement separator. 00:32 < mightybyte> More a separator than a terminator. 00:32 < aep> right. statement not command 00:32 < aep> i've seen how do combines stuff into an "action" 00:32 < mightybyte> Do you understand anything about the Maybe monad? 00:32 < aep> its a monad?! 00:33 < aep> i thought it is a type 00:33 < mightybyte> Yep :) 00:33 < mightybyte> It's that too 00:33 < aep> heh 00:33 < mightybyte> Any type that takes a single type parameter can be a monad. 00:33 < aep> i used it, yes, but unaware that it rewpresents a monad 00:33 < mightybyte> i.e. things that are monads are container types 00:34 < aep> well IO has a paremeter 00:34 < mightybyte> Well, Maybe is used to represent an optional value 00:34 < mightybyte> The Monad instance for Maybe is what makes it really cool. 00:35 < mightybyte> instance Monad Maybe where 00:35 < mightybyte> (Just x) >>= k = k x 00:35 < mightybyte> Nothing >>= k = Nothing 00:35 < mightybyte> return = Just 00:35 < aep> hmm 00:35 < mightybyte> The Monad type class requires two main functions 00:35 < mightybyte> bind and return 00:35 < mightybyte> bind is represented by the infix operator >>= 00:36 < aep> thats the one used to combine 00:36 < aep> *computations 00:36 < mightybyte> Yeah 00:37 < aep> does that mean k(Just x) is the same as k(x) ? 00:37 < mightybyte> (>>=) :: m a -> (a -> m b) -> m b 00:37 < aep> yeah 00:38 < mightybyte> So bind takes a monadic value (which means a value inside some monad box) 00:38 < mightybyte> And a function that operates on the pure version of that value, generating another monadic value. 00:38 < mightybyte> It strips off the monadic container from the value and applies the function to it. 00:38 < aep> right 00:38 < mightybyte> ...returning the new monadic value. 00:39 < mightybyte> Think about checking for NULL in C 00:39 < aep> that's why you can pass Maybe x to a function expecting x i guess 00:39 < mightybyte> That's what bind does in the Maybe monad. 00:39 < mightybyte> Right 00:39 < mightybyte> If the incoming value is Nothing, then bind just returns Nothing. 00:39 < mightybyte> It short-circuits the computation. 00:40 < aep> without consulting k. obvious 00:40 < aep> aah so when you combine multipl computations you can sort of break out of the chain by returning Nothing from one computation 00:41 < mightybyte> Yes 00:42 < mightybyte> If the value is a Just, then it gets stripped off, and the plain value gets passed to k, which generates another maybe. 00:42 < mightybyte> So imagine that you have a sequence of computations in C. 00:42 < mightybyte> Call them f, g, and h 00:43 < mightybyte> Each of these computations returns a pointer that might be null. 00:43 < mightybyte> Maybe the first one gets a string from somewhere representing a filename 00:43 < mightybyte> Then it uses that to open a FILE *. 00:43 < aep> yeah 00:44 < mightybyte> And then uses that to read another string out of the file. 00:44 < aep> well those are all different types. i dont think you can do that in a monad, can you? 00:45 < mightybyte> So the chain is (char * -> FILE * -> char *) 00:45 < mightybyte> Any three of these computations might fail. 00:45 < mightybyte> Yes you can--because the type has a single type parameter. 00:45 < aep> you can only combine computations of the same monad instance 00:45 < aep> hm 00:45 < mightybyte> So in good C code, you'd need to write a null pointer check after each one of the three operations 00:46 < mightybyte> ...because any one of them might fail and prevent the next one(s) from working 00:46 < aep> yeah 00:47 < aep> with Maybe, the entire computation returns null if one does, without consulting the rest 00:47 < mightybyte> But in Haskell, the Maybe monad defines ';' as the null check. 00:47 < mightybyte> Of course, it's not ';'. It's the bind function. 00:47 < mightybyte> Right 00:47 < mightybyte> So in Haskell, our types would look like this: 00:47 < mightybyte> f :: blah -> Maybe String 00:47 < mightybyte> g :: String -> Maybe File 00:47 < mightybyte> h :: File -> Maybe String 00:48 < mightybyte> And we can do this: 00:48 < mightybyte> f arg >>= g >>= h 00:48 < mightybyte> And all the null checks will happen automatically 00:48 < aep> which is :: Maybe String ? 00:48 < mightybyte> Right 00:49 < mightybyte> So Monad are an abstraction that provides an incredibly useful way of avoiding boilerplate. 00:49 < mightybyte> *Monads 00:50 < aep> so a monad defines what >>= actually does? 00:50 < mightybyte> Yes 00:50 < aep> wow 00:50 < aep> well that was easy 00:50 < aep> why did no one tell me?! :D 00:50 < mightybyte> Monad is a type class 00:50 < mightybyte> In order for something to be a monad, it has to define >>= and return 00:50 < mightybyte> And that's it. 00:51 < aep> well what does return do? 00:51 < aep> stick a pure value into a box? 00:51 < mightybyte> Return just stuffs a plain "unboxed" value into the box. 00:51 < mightybyte> Yep 00:51 < aep> so what is lift? 00:51 < mightybyte> Hmm, I still have to look that one up. 00:52 < aep> that was in the first example of happs 00:52 < aep> lost me 00:52 < aep> i <- lift $ modify (+1) =>> get =>> return . show $ i 00:53 < aep> err wrong. without the return 00:53 < mightybyte> lift is defined in Control.Monad.Trans 00:53 < mightybyte> lift :: (MonadTrans t, Monad m) => m a -> t m a 00:53 < aep> riight transformers. i have no idea what those do 00:54 < aep> stick one monad into another? 00:54 < mightybyte> Yeah, kind of. 00:54 < mightybyte> Where did you see that example code? 00:54 < mightybyte> To understand that line, first you need to understand the state monad. 00:55 < aep> http://tutorial.happstack.com/src/StateTExample.hs 00:56 < aep> i guess i simply didnt understand the nessesity of lift before i knew what a monad is 00:56 < aep> now it makes sort of sense 00:57 < mightybyte> lift is a function defined by MonadTrans 00:57 < mightybyte> http://hackage.haskell.org/packages/archive/mtl/1.1.0.2/doc/html/Control-Monad-Trans.html 00:58 < mightybyte> So Happstack defines the lift function for the ServerPartT monad 00:59 < mightybyte> Now I think you should be able to read and understand RWH chapter 14 00:59 < aep> will do that. thanks for your help! 01:00 < mightybyte> Then you can read this 01:00 < mightybyte> http://www.haskell.org/all_about_monads/html/index.html 01:00 < mightybyte> And other things that show up when you google "monad tutorial" 01:02 < mightybyte> That tutorial has descriptions of some of the most common monads. 01:02 < aep> cool 01:02 < mightybyte> Like the reader monad. 01:03 < mightybyte> That's really just a way to eliminate the boilerplate involved in having global read-only data. 01:03 < mightybyte> How would you do that without monads? 01:04 < mightybyte> You'd have to pass it as a parameter to every function in the whole chain of functions that need access to the data. 01:04 < aep> thats exactly what i did in my programs oO 01:04 < mightybyte> It's repetitive 01:04 < aep> totally 01:04 < mightybyte> The reader monad provides a way to eliminate the repetition. 01:05 < aep> for example i have some int which i need for counting. how would i use a monad to remove the passing around? 01:05 < aep> ah 01:05 < mightybyte> For that, you'd probably use the State monad. 01:06 < mightybyte> Just remember, a monad is a box. 01:06 < aep> right. but i still have to pass the box around 01:06 < mightybyte> The Maybe monad is a box that also indicates whether the computation failed 01:06 < mightybyte> The Reader monad is a box that carries another value with it 01:07 < mightybyte> The State monad is a box that carries a value and allows you to modify that value along the way 01:07 < aep> hmm 01:08 < mightybyte> Go through the RWH monad chapters and the monad tutorial at that link. I think you're well on your way. 01:08 < aep> i just tried rwh again. i hate it :( 01:08 < mightybyte> After that, let me know if things are still unclear. 01:08 < aep> pages and pages of irrelevant text and no mentioning of what you showed me 01:08 < aep> i'll try the other link 01:09 < aep> begins ALOT better :D "a monad is..." 01:09 < mightybyte> At the beginning of chapter 14, they're basically showing you the same idea I just described with the Maybe monad. 01:10 < aep> yeah, just in a really complex way 01:10 < mightybyte> You could also skip down to the RWH section "The Monad typeclass" 01:10 < aep> RWH is definatly one of the worst books i've ever read 01:10 < mightybyte> The stuff before that is mainly describing the motivation. 01:10 < mightybyte> I actually thought it was pretty decent. 01:11 < mightybyte> But there are many different learning styles. 01:11 < aep> yeah. i prefer knowing what it is about instantly then learn the details. RWH is the other way rpound 01:11 < aep> lots and lots of details and the actual "what it is" is at the very end 01:11 < mightybyte> (Although I haven't actually read much of RWH in-depth. 01:12 < mightybyte> I think both ways are useful. 01:12 < mightybyte> I found it hard to really appreciate the significance of what a monad is just from the plain description of what it is. 01:13 < aep> yeah me too, but you showed it in very few words 01:13 < aep> you should write a book :P 01:13 < mightybyte> Heh 01:14 < mightybyte> Well, I'm relatively new to Haskell, so the plight of the beginner is fairly fresh in my memory. 01:15 < mightybyte> Another resource that's really good is Brent Yorgey's "Typeclassopedia" 01:16 < mightybyte> He goes through most of the foundational typeclasses in Haskell. 01:16 < mightybyte> It definitely gave me some nice "AHA!" moments. 01:16 < aep> cool thanks 01:17 < mightybyte> That one you should probably read roughly in order. 01:17 < mightybyte> Don't just jump down to the monad chapter. 01:17 < mightybyte> Well, I need to get going. 01:17 < mightybyte> Good luck in your learning. 01:19 < aep> thanks 01:55 < aep> mightybyte1: the all_about_monads tutorial you linkes is _great_ 05:44 < koeien> zomg, monad tutorials in #happs 06:38 < HugoDaniel> ghci segfaulted again :( 06:38 < HugoDaniel> i was runing happs 06:39 < HugoDaniel> and then i ctrled+c to stop it, and loaded another module (that has nothing to do with happs), it found some syntax errors and segfaulted in the next prompt 09:05 < HugoDaniel> hmm, another segfault 09:05 < HugoDaniel> this is getting ugly 10:02 < mightybyte1> What version of Happstack? 10:08 < aavogt> I think I've seen this too: does your app set up a handler for C-c? 10:08 < aavogt> that being waitForTermination --- Log closed Thu Jan 07 10:24:49 2010 --- Log opened Thu Jan 07 10:24:49 2010 --- Log closed Thu Jan 07 10:24:49 2010 --- Log opened Thu Jan 07 10:24:53 2010 10:59 < HugoDaniel> im using the latest happstack version 10:59 < HugoDaniel> the last one that got released 10:59 < HugoDaniel> happstack-server-0.4.1 this one, right ? 11:02 < mightybyte1> Ok. I haven't used that version yet. 11:06 < HugoDaniel> i was also getting these errors with 0.3.2 11:12 < mightybyte1> Hmmm, I don't know anything about this problem. --- Log closed Thu Jan 07 11:13:33 2010 --- Log opened Thu Jan 07 11:13:33 2010 --- Log closed Thu Jan 07 11:13:33 2010 --- Log opened Thu Jan 07 11:13:37 2010 11:13 < mightybyte1> If you can come up with a reliable test case that demonstrates the problem, file it as a bug and it should get some attention. --- Log closed Thu Jan 07 11:15:13 2010 --- Log opened Thu Jan 07 11:15:13 2010 --- Log closed Thu Jan 07 11:15:13 2010 --- Log opened Thu Jan 07 11:15:16 2010 11:51 < HugoDaniel> its byzantic 11:52 < HugoDaniel> i have already tried to do that :/ 11:52 < HugoDaniel> byzantine 18:14 < stepcut> hrm. massInput and controls which can return a list of 0 elements are not good friends.. 18:46 < stepcut2> mightybyte1: I think massInput is still broken :-/ 18:47 < stepcut2> specifically, for , massInput (optionalInput $ \name -> ...) 18:47 < stepcut2> optionalInput will always succeed, even if no value was submitted.. 18:48 < stepcut2> so how does it know when to stop? I think it will just assume an infinite number of Nothing values were submitted.. 19:34 < pham> how do you create an empty XML fragment? 19:35 < pham> say I have a function like: my_page content = withMetaData html4Strict $ ...<% content %> 19:35 < stepcut> pham: there is no such thing as an empty XML fragment 19:36 < pham> how do I call my_page such that I get nothing in the tag? 19:36 < stepcut> the XML designers failed to make XML a monoid :( 19:36 < stepcut> my_page () 19:43 < pham> stepcut: yeah, I was looking at the instances hoping monoid would be in there 19:43 < stepcut> pham: nope. just another way that XML blows :p 19:43 < pham> my instinct was to do: my_page mzero 19:44 < pham> ;) 19:44 < stepcut> in HSP though, () gets turned into nothing 19:45 < stepcut> well, provided that there is an, EmbedAsChild m (), for the 'm' you are using. But for the standard XMLGenerator instances that is always provided 19:45 < stepcut> mightybyte1: 'finished' merging my formlets patches, except that I think I uncovered that massInput bug.. http://github.com/stepcut/formlets/tree/remove-xml-monad 19:46 < stepcut> I ran some tests, and it seems to be working otherwise 19:47 < stepcut> sadly, the FormResult thing made the code messier 19:47 < stepcut> in our code, input' and optionalInput were implemented as functions that called generalInput 19:48 < pham> grr, I'm getting an "Ambiguous type variable" from my_page, but if I tell it the argument is "HSP XML" than it complains that "()" isn't of type "HSP XML" 19:48 < stepcut> but I could not do that with the FormResult stuff now.. which is ok.. unless the FormResult stuff doesn't actually fix massInput ;) 19:48 < pham> what type should the argument be? 19:48 < stepcut> what is the type of my_page ? 19:48 < pham> the types behind HSP and Happstack are a little overwhelming 19:48 < stepcut> pham: yes they are.. and not well documented 19:48 < stepcut> pham: a major focus for happstack now is addressing that 19:49 < pham> ah, in an example they give the type " 19:50 < pham> (EmbedAsChild (HSPT' IO) xml) => xml -> HSP XML 19:50 < pham> (yikes) 19:50 < pham> but it makes sense 19:50 < stepcut> yeah 19:51 < stepcut> the HSPT' and HSP types are a bit annoying. I am going to merge some patches into happstack soon so that you don't have to use them :) 19:51 < stepcut> but, it wouldn't change the issue you are having now 19:53 < pham> and I need -XFlexibleContexts 19:53 < stepcut> yep 19:55 < pham> eeks, it gets real awkward with two arguments: 19:55 < pham> template_splash :: (EmbedAsChild (HSPT' IO) x1, EmbedAsChild (HSPT' IO) x2) => x1 -> x2 -> HSP XML 19:55 < pham> :) 19:56 < stepcut> bah, that's nothing. Here is a type signature from a function I wrote, 19:56 < stepcut> boardTemplate :: ( Functor m, MonadIO m, MonadPlus m, XMLGenerator m, FilterMonad Response m, WebMonad Response m, ServerMonad m, EmbedAsChild m headers, EmbedAsChild m body, EmbedAsChild m (HJScript ()), EmbedAsChild m (), EmbedAsChild m XML, (HSX.XML m) ~ XML, ShowURL m, URL m ~ WebURL, MonadConfig m) => WebURL -> (Either ThreadId (BoardName, Int)) -> String -> headers -> body -> XMLGenT m (HSX.XML m) 19:57 < stepcut> ;) 19:59 < pham> makes me wonder about applying static typing to HTML templates 19:59 < stepcut> oh ? 20:00 < stepcut> HSP is static type for HTML templates :-/ 20:19 < McManiaC> Prelude> let x ? y= (x + abs y, x - abs y) 20:19 < McManiaC> <3 20:19 < McManiaC> :D 20:58 < mightybyte1> stepcut: Hmmm, making massInput work with optionalInput seems like a tough problem. 21:07 < stepcut> mightybyte1: yes 21:08 < stepcut> mightybyte1: I'm not sure if that is even a sensible thing to do... 21:09 < mightybyte1> Yeah, it really doesn't make sense to have a non-existant item in a list. 21:09 < stepcut> yeah 21:09 < stepcut> the current API doesn't stop you from trying though ;p 21:09 < mightybyte1> Sure 21:10 < stepcut> anyway, I pushed all our patches now... let me know if you have questions about anything 21:10 < mightybyte1> Ok. 21:10 < mightybyte1> So you think this is reasonably ready for release? 21:11 < stepcut> for examples that use generalInput and generalInputMulti, see, http://src.seereason.com/happs-hsp-formlets/HSP/Formlets.hs 21:11 < stepcut> the HSP.Formlets stuff is not ready for prime time yet, but it does show how to use it 21:12 < mightybyte1> Ok 21:12 < stepcut> I have not tested it exhaustively, but the tests I did do were successful 21:12 < stepcut> I tested input', generalInput, and generalInputMulti. But not optionalInput or massInput 21:13 < mightybyte1> Ok. I've got plenty of code that uses massInput 21:13 < stepcut> I don't know of anything wrong or have specific reasons to believe that I broken anything though 21:13 < stepcut> so, if it works for you, then it's probably good 21:13 < mightybyte1> Ok 21:14 < stepcut> it'll be nice to not be using a fork anymore :) 21:14 < stepcut> means I can finally release some libraries I have that build on top of formlets (mostly Happstack/HSP related stuff) 21:15 < mightybyte1> Yeah, this will be a good improvement 21:20 < mightybyte1> Did you issue a pull request? 21:26 < stepcut> um.. there is more to it than tell you on IRC? 21:28 < stepcut> ok I clicked on the pull request button, now to fill in some fields. 21:28 < stepcut> who is eelco? 21:30 < stepcut> ok, sent! 21:34 < pham> how do I add a handler that matches an exact path and serves out an HSP XML page? 21:34 < pham> specifically the path "/"? 21:36 < mightybyte1> stepcut: Oops, sorry I wasn't watching. I wasn't meaning that you needed to. Just wondering if you did. 21:40 < stepcut> pham: nullDir $ ok (toRespnose "foo") 21:40 < pham> ah "ok" is the function I was looking for 21:41 < mightybyte1> stepcut: Looks like all the pull request does is send me a github message. 21:41 < stepcut> mightybyte1: impressive! 21:41 < mightybyte1> Heh 21:42 < mightybyte1> In the past I've had problems getting their Fork Queue interface to merge things properly. 21:42 < mightybyte1> My manual pull from you just now worked perfectly. 21:42 < stepcut> :) 21:44 < mightybyte1> Ok. Now your changes are in the remove-xml-monad branch in the main repository. 21:44 < mightybyte1> As soon as I get it working with my app I'll move it to master. 21:44 < stepcut> neat! 21:44 < stepcut> the only changes that should affect your app are the ones you made to remove-xml-monad 21:45 < mightybyte1> Oh really? 21:45 < mightybyte1> Ok 21:45 < mightybyte1> Great 21:46 < mightybyte1> Is there anything new in the latest darcs head for happstack that would benefit me over the hackage release? 21:48 < pham> man I don't get this ServerMonad 21:49 < stepcut> mightybyte1: don't think so.. 21:49 < mightybyte1> Ok 21:50 < mightybyte1> And happstack-extras works with your formlet mods? 21:50 < stepcut> mightybyte1: not yet 21:50 < stepcut> mightybyte1: but I could do that tomorrow 21:51 < mightybyte1> Hmmmm, that would help. I think my app depends on that. 21:51 < stepcut> ok, so do mine :) 21:51 < stepcut> I'll start work on that in approximately 12 hours 21:51 < mightybyte1> Thanks 21:51 < stepcut> shouldn't take long... the arguments to runFormState changed.. 21:51 < pham> stepcut: "nullDir $ ok (toRespnose "foo")" results in the type error: Couldn't match expected type `ServerPartT IO Response' against inferred type `()' 21:53 < stepcut> oops, that should be, nullDir >> ok (toResponse "foo") 21:53 < stepcut> or, do { nullDir ; ok (toRespnose "foo") } 21:54 < pham> ah, that makes more sense, because nullDir :: (ServerMonad m, MonadPlus m) => m () 21:54 < pham> and hence doesn't take any arguments :) 21:55 < stepcut> yes 21:55 < pham> so >> in the ServerMonad applies request conditions? 21:55 < stepcut> um.. 21:56 < stepcut> not really 21:56 < stepcut> ServerMonad is just a ReaderMonad that contains the Request 21:57 < stepcut> the behaviour of nullDir is because, nullDir :: (ServerMonad m, MonadPlus m) => m (), requires 'm' to be an instead of MonadPlus 21:57 < stepcut> so nullDir just calls mzero if the directory is not 'null' 22:00 < stepcut> ...to be an *instance* of MonadPlus... 22:00 < stepcut> clearly it is bedtime for me :) 22:04 < pham> I kind of get it, I think 22:04 < pham> I need to write a bunch of happstack code 22:04 < stepcut> yes 22:04 < stepcut> and read some awesome tutorials that have not been written yet :) 22:05 < stepcut> I guess I don't really think of >> as doing anything :-/ 22:06 < mightybyte1> stepcut: Wow, "darcs pull" on happstack-extra is taking a REALLY long time. 22:07 < stepcut> mightybyte1: hmm. I have been have issue with darcs hanging... 22:10 < stepcut> mightybyte1: the apache log does not show any new requests from you since :53 22:10 < stepcut> I would just kill it and try again 22:10 < mightybyte1> Hmm, looks like it's making some progress. 22:10 < mightybyte1> Up to 84/142 22:11 < stepcut> there are also apparently two different search engines crawling the archive right now.. 22:12 < stepcut> maybe they are sucking up the bandwidth 22:12 < mightybyte1> Heh 22:12 < mightybyte1> More progress. Almost done. 22:13 < stepcut> yeah, I am not sure what is going on -- if it is an issue with darcs or with apache 22:37 < mightybyte1> Hmmm, restarting just makes it start over. 22:43 < stepcut> :-/ 22:44 < stepcut> beats me 22:44 < stepcut> go darcs! 22:44 < mightybyte1> :( 22:44 < mightybyte1> go git! 22:44 < mightybyte1> :P 23:20 < pham> how do you turn an "HSP XML" in to a "Response"? 23:33 < pham> why doesn't HSP XML have a Response instance? 23:41 < pham> I have to manually convert it with webHSP? --- Log closed Fri Jan 08 00:00:06 2010