On Tue, Mar 16, 2010 at 11:05 PM, Michael Snoyman <michael@snoyman.com> wrote:

My new version has two typeclasses, I'll copy them in their entirety here:

class IsRelPath a where
    toRelPath :: a -> RelPath
    fromRelPath :: RelPath -> Maybe a

class IsRelPath (Routes a) => WebPlug a where
    type Routes a
    dispatch :: a -> Routes a -> (Routes a -> AbsPath) -> Application

I think we all agree that IsRelPath 1) needs to exist and 2) should be called something better than that. I would say that it's useful to have dispatch as part of a typeclass, which is what WebPlug now is. What makes this typeclass so convenient is that any instance of WebPlug is *self contained*. There's no need to keep track of which subapps require which arguments.


I am not really clear wath the benefit for WebPlug is -- it seems to me that it is just adding more boilerplate..

I added two new modules to URLT, namely URLT.Wai and URLT.Dispatch.

I think implemented your little blog demo twice. Once where I didn't use dispatch, and once were I did. The code for that is here:

http://src.seereason.com/urlt/WaiExample.hs

It seemed like using dispatch did not get rid of or simplify anything, it just added more boiler plate, type classes, and used extensions (type families) that a lot of people don't understand yet.

And instead of writing something short a straigt-forward like:

 handleWai mkAbs fromAbs (mySite now)

I had to write the longer:

 handleWai mkAbs fromAbs (dispatch (SiteArgs (BlogArgs now)))

And on the handler end, it hide useful information in the type signature and required more constructor matching. Instead of:

myBlog :: UTCTime -> (BlogURL -> String) -> BlogURL -> Application
myBlog now mkAbs BlogHome _request =

I have:

myBlogD :: BlogArgs -> (BlogURL -> String) -> BlogURL -> Application
myBlogD (BlogArgs now) mkAbs BlogHome _request =

In order to know the type of 'now' I have to go look somewhere else. In 'myBlog' it was right there in the type signature.

So, I guess I do not yet see the value of Dispatch. On the plus side, it doesn't seem like I have to use it if I don't like it. But I am curious if I am missing something useful here..

One advantage is that I can do:

:info Dispatch

in GHCi, and see all the Dispatch instances that are available. But I'm not sure that really makes it worth the effort.

- jeremy

p.s. The WaiExample does not use AsURL  / IsRelPath, because that is really a completely orthogonal issue, and I wanted to cut out anything that was not relevant.