01:18:40 <mm_freak> stepcut: it's based on pipes anyway, so just let the handler be a consumer
01:59:43 <stepcut> mm_freak: but how do you prevent the handler from consuming too much or not consuming enough?
02:00:13 <mm_freak> stepcut: you don't
02:00:25 <mm_freak> the handler should be free to consume as much as it wants
02:01:06 <stepcut> so, if the handler decides to ignore the POST request body, then it should just screw up any other following requests in the persistent connection?
02:02:31 <mm_freak> not necessarily…  use pipes-parse to split the stream into individual requests
02:02:44 <mm_freak> that's a generalized 'isolate' from conduit/enumerator
02:02:56 <stepcut> that would require the handler to be in the StateT monad transformer then?
02:03:17 <mm_freak> if it wants to
02:03:29 <mm_freak> the stream of requests would be a FreeT over a Producer
02:03:44 <mm_freak> that Producer can be wrapped in a StateT for finding EOFs
02:04:22 <stepcut> I don't really understand what you are proposing
02:05:10 <stepcut> at the top-level I have a stream which contains multiple HTTP requests, I want to parse the headers, and then hand control off to a user supplied handler which can then choose to do something with the request body
02:05:38 <stepcut> that handler should not be able to parse beyond the end of the request body, and if it ignores the request body, then we still need to discard it afterwards
02:05:58 <mm_freak> requestChunks :: FreeT (StateT (Producer ByteString m) m) m r
02:06:01 <mm_freak> something like that
02:06:09 <mm_freak> requestChunks :: Producer ByteString m r -> FreeT (StateT (Producer ByteString m) m) m r
02:06:19 <mm_freak> turns a raw bytestring stream into a stream of request chunks
02:06:36 <stepcut> so what type does the user supplied handler function have?
02:07:04 <stepcut> in theory, (Monad m) => Request -> m Response, would be nice -- but that isn't going to work as far as I can tell
02:07:06 <mm_freak> StateT (Producer ByteString m) m r
02:07:26 <mm_freak> StateT (Producer ByteString m) m Response
02:07:53 <mm_freak> this handler gets the raw bytestring stream
02:08:18 <stepcut> so, what ensures that it does not screw up the raw bytestring stream ?
02:08:21 <mm_freak> then there is a predefined request parser that parses everything and returns a producer for the body (for handling transfer encodings)
02:10:10 <stepcut> so, that StateT thing is one of the solutions I came up with
02:10:55 <stepcut> I think what I would need to do is create a newtype wrapper that wraps up the StateT (Producer ByteString m), but doesn't give the user handler direct access to it such that I can enforce some rules and guarantees
02:12:33 <stepcut> https://groups.google.com/d/msg/haskell-pipes/gBIwod3Lylo/EOX2Iv22E3cJ
02:15:43 <stepcut> I think my only real options are StateT or IORefs
02:15:47 <stepcut> and I'd rather stay pure
02:15:52 <stepcut> so StateT
02:17:24 <mm_freak> that would be terribly awkward to work with
02:17:53 <mm_freak> you would end up wrapping and unwrapping all the time…  and you couldn't read the meaning right from the type signature
02:18:11 <mm_freak> remember, this is low level…  there is no need to hide the pipes-parse interface =)
02:18:28 <mm_freak> note that pipes-parse has direct support for that StateT-based stuff
02:18:57 <mm_freak> so it's really the way you do it in pipes…  the type is precise and reasonable
02:19:29 <stepcut> StateT would be awkward to work with ?
02:20:01 <stepcut> or the newtype?
02:21:32 <mm_freak> the newtype
02:22:28 <stepcut> so you are arguing for letting the user shoot themselves in the foot?
02:24:29 <stepcut> the warp API is basically, Request -> IO Response, and, requestBody :: Source (ResourceT IO) ByteString. You can't read too much from the request body (even if you tried), and if you don't read all if it, the rest gets discarded. That is pretty fool-proof
02:24:46 <stepcut> but it does its magic using an IORef I am pretty sure
02:25:31 <stepcut> I don't want to be fielding questions about mysterious parsing errors that result from people doing things that the system lets them -- even though they shouldn't be doing it..
02:25:55 <stepcut> if they shouldn't directly get/put the producer in the StateT -- then I don't want to let them..
02:26:15 <stepcut> or.. it should at least appropriately inconvenient to do so
02:26:44 <mm_freak> how can you shoot yourself in the foot with the StateT variant?
02:27:31 <mm_freak> it's not fundamentally wrong to access the state directly…  it's not even wrong to replace it
02:27:32 <stepcut> my belief is that it allows the user handler to mess up the stream that the next request will be read from ?
02:27:37 <mm_freak> in fact it may prove useful for some applications
02:27:45 <mm_freak> no, that's impossible
02:28:00 <mm_freak> the substreams are separated by FreeT's delimiting
02:28:07 <stepcut> ah
02:28:31 <stepcut> then I am ok with that solution
02:28:32 <mm_freak> in fact the substream handler doesn't even have a way to know that there is a wrapping FreeT
02:28:40 <mm_freak> it's quite elegant =)
02:28:43 <stepcut> I will make a go at it tomorrow
02:28:55 <mm_freak> as most of Tekmo's solutions are =)
02:29:08 <stepcut> indeed
02:29:16 <stepcut> my solution was not elegant, so I figured I must be doing something wrong ;)
02:31:02 <mm_freak> =)
14:01:34 <ocharles> hallo
14:02:27 <ocharles> I'm playing with web-routes-boomerang again - is there a way to validate the result of a parser? Specifically, I want to do something like int >>= guard . (> 0)
14:02:40 <ocharles> (rudely pinging stepcut)
14:02:55 <stepcut> hmm
14:03:31 <ocharles> I haven't quite got all the intuition of what composition of boomerangs really means, but it seems that isn't what I want
14:03:36 <ocharles> composition under the category, that is
14:05:23 <stepcut> rFilter perhaps? http://hackage.haskell.org/package/boomerang-1.4.0/docs/Text-Boomerang-Combinators.html#v:rFilter
14:06:43 <ocharles> that doesn't error, from what I can see
14:06:51 <ocharles> so I'd end up with an empty list
14:07:03 <ocharles> but I haven't actually tried it, so let me have a noodle in ghci
14:07:38 <ocharles> > parse (rFilter (> 0) int) ["-1"]
14:07:38 <ocharles> []
14:07:39 <lambdabot>   Not in scope: `parse'Not in scope: `rFilter'
14:07:39 <lambdabot>  Perhaps you meant one of thes...
14:07:39 <ocharles>  
14:07:50 <ocharles> ssshhhh, lambdabot, sssshhh
14:08:00 <ocharles> so it doesn't fail or pass :)
14:09:32 <ocharles> though it looks like web-routes-boomerang will fail to interpret that, which may be enough
14:11:47 <ocharles> ok, that does get me to a 500 which does the job for now
14:12:09 <stepcut> yeah, boomerang returns a list of all successful parses, but web-routes-boomerang picks the longest successful parse-- and there must be at least one
14:12:24 <ocharles> A bit of a shame I can't add more diagnostics to my error log as to why it failed, but never mind
14:12:26 <stepcut> a 500 :-/
14:12:32 <ocharles> a 500 by choice
14:12:36 <stepcut> ah
14:12:41 <BoR0> hi, I am running the helloBlaze example from the documentation and it works fine. now, I want to combine it with simpleHTTP nullConf $ msum [ dir ... ], but it says that it can't match Response with [Char], which is natural. how can I solve this?
14:12:45 <ocharles> runSite returns Left
14:12:55 <stepcut> BoR0: toResponse ?
14:13:15 <BoR0> helloBlaze returns a Response, but dir "test" $ x is expecting x to be string I think
14:13:24 <BoR0> I try this and it doesn't work:  dir "test"     $ helloBlaze
14:14:14 <stepcut> can you paste the code on lpaste.net ?
14:14:31 <BoR0> sure, one sec
14:19:32 <stepcut> ACTION hopes BoR0 knows how to copy and paste and isn't retyping the entire programming into lpaste.net
14:19:44 <BoR0> haha
14:19:54 <BoR0> I'll just copy and paste everything, I tried to paste the relevant part but without success
14:20:00 <stepcut> :)
14:20:12 <lpaste> BoR0 pasted “test happstack” at http://lpaste.net/96232
14:20:20 <BoR0> line 59
14:20:28 <stepcut> pasting the whole thing is often useful so that I can compile it and check things for myself
14:20:42 <stepcut>     [ dir "hello"    $ ok $ "Hello"
14:21:05 <stepcut> that line is making the type-checker think you want [ServerPart String]
14:21:20 <stepcut> so when you have a ServerPart Response later in the list it is unhappy
14:21:23 <BoR0> so if I were to mix different types, how could I do it?
14:21:29 <BoR0> should I make my own data?
14:21:33 <stepcut> dir "hello" $ ok $ toResponse "Hello"
14:21:57 <stepcut> I would just convert everything to be Response unless you have some really good reason not to
14:22:19 <BoR0> I will try what you suggested, thanks
14:26:51 <BoR0> I am struggling with the types, aaargh
14:27:01 <lpaste> BoR0 revised “test happstack”: “No title” at http://lpaste.net/96232
14:27:22 <BoR0> could you please check the latest edit? I can't get them to match
14:30:49 <stepkut> you need something like:
14:30:50 <stepkut> dir "hello"    $ ok $ toResponse ("Hello" :: Text)
14:31:15 <BoR0> wow, phew. what a struggle. :: String fixed it, thanks
14:31:17 <stepkut> because you have OverloadedStrings enabled -- so it doesn't know what type "Hello" is, so it can't figure out which 'toResponse' function to call
16:40:17 <dcoutts> IsString really ought to have defaulting
16:40:26 <dcoutts> like the other builtin classes
16:53:09 <donri> i think it does with EDR?
17:04:14 <donri> not sure it would work in this case though (plus IsString probably should have defaulting without EDR, since you get a lot of extra crazy with EDR)
17:05:02 <donri> and in this case it's arguably a good thing we don't get defaulting
17:05:20 <donri> since ("Hello" :: Html) would render with a different content-type
17:05:33 <donri> so it's not simply a matter of selecting the best text representation
17:12:55 <donri> although i guess if the default is sensible (like String) and overridable (like "default"), it's not so bad...
18:17:40 <dcoutts> donri: the problem at the moment is if you switch on overloaded strings then we break lots of stuff because of unresolved overloading
18:18:46 <donri> yeah