Hi Jeremy,

I've CCed the web-devel list, as I think the discussion will be of interest to a number of readers there.

When we were originally working on web-routes, you had mentioned the idea of including some form of support for query strings, and I said it was a bad idea. I'd like to backtrack on that statement: I *would* like to include support, and I'm including a patch that does just that. Let me explain the use case this is meant to serve, which will help explain my design decisions.

Yesod includes a static file subsite. One trick a lot of sites are using these days is including a hash of the file contents in the query string of the URL and setting the expiration date of the file far in the future. This way, as long as the file contents stay the same, the browser should use the cached copy, and as soon as a new version is available, the HTML will reflect this by a change in the hash value.

I wanted to provide this feature with Yesod, but realized there was no straight-forward way to do this. What I needed was to change the formatPathSegments function to have a type signature of: url -> ([String], [(String, String)]), where the second element in the tuple is the query-string parameters. This, however, presents a small problem: let's say that we want to add query string parameters *on top of* those provided by the formatPathSegments function; we could do manually addition textually, but we won't know whether to include is as "?foo=bar" or "&foo=bar"; the former should be used if formatPathSegments does not given any query string parameter, the latter if it does.

I therefore modified the handleSite function to be: (url -> [(String, String)] -> String) -> url -> a. I also changed encodePathInfo to also encode the query string parameters, so its type is now: [String] -> [(String, String)] -> String. All the other changes were just to get the code to compile.

I'm planning on this being a change throughout a few other libraries: web-routes-quasi will obviously change to reflect this, as will Yesod. One other perhaps unexpected change would be in Hamlet: the definition of Hamlet is now "type Hamlet = (url -> [(String, String)] -> String) -> Html ()". One nice side effect of this is query-string encoding code is now completely localized to web-routes, instead of copied throughout multiple packages. This at least implies to me that this is a good move.

You'll notice that I have purposely *not* modified decodePathInfo and parsePathSegments; I still don't believe routing should be affected in any way by query string parameters.

Look forward to hearing your thoughts on this,
Michael