
On 16 mrt 2010, at 17:51, Gregory Collins wrote:
Michael Snoyman
writes: I think the only piece of the puzzle missing to combine these two together is to have mkResources output something along the lines of:
data RoutePiece = StaticPiece String | IntPiece | StringPiece _validRoutes :: [[RoutePiece]] _validRoutes = [ [StaticPiece "user"] , [StaticPiece "user", StaticPiece "find", IntPiece] , [StaticPiece "user", StaticPiece "name", StringPiece] ]
Yes, this approach smells a lot better to me: the types are types and the data are data. Just a brainstorm: if each handler monad were to carry its routing table around with it, you could define something like:
match :: ByteString -> (WhateverYourWebMonadIsCalled a) -> (WhateverYourWebMonadIsCalled a)
And write
handler = match "/foo/:bar/#int/" $ do ...
without the template haskell quasiquotation (i.e. do the checking at runtime.) Is it always true that compile-time link checking is possible/desirable? All of these solutions also imply that each handler knows where it's hung on the routing table so that it can resolve relative URLs, etc.
IMO no matter what a link-checker should be lightweight enough that you can refactor easily without rewriting a bunch of static tables; you should be able to move an entire "subtree" to another place in the routing table in O(1) time.
This rabbit hole goes pretty deep though; if you're serious about the bondage and discipline approach you'd want to ensure that you can check query parameters; i.e. "'/foo' takes a mandatory 'bar' integer parameter on the queryString and an optional 'sort' parameter which must be either 'asc' or 'desc'", etc. At some point I have to wonder: is the medicine worse than the disease?
This would be a fairly straightforward extension of my library. I'll see if I can come up with something on the trainride to ZuriHac tomorrow! -chris