On Tue, Mar 16, 2010 at 11:05 PM, Michael Snoyman <span dir="ltr">&lt;<a href="mailto:michael@snoyman.com">michael@snoyman.com</a>&gt;</span> wrote:<br><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<div><div></div><div class="h5"><br></div></div><div>My new version has two typeclasses, I&#39;ll copy them in their entirety here:</div><div><br></div><div><div>class IsRelPath a where</div><div class="im"><div>    toRelPath :: a -&gt; RelPath</div>
<div>    fromRelPath :: RelPath -&gt; Maybe a</div>
<div><br></div></div><div>class IsRelPath (Routes a) =&gt; WebPlug a where</div><div>    type Routes a</div><div>    dispatch :: a -&gt; Routes a -&gt; (Routes a -&gt; AbsPath) -&gt; Application</div><div><br></div><div>
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&#39;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&#39;s no need to keep track of which subapps require which arguments.</div>

<div><br></div></div></blockquote><div><br></div><div>I am not really clear wath the benefit for WebPlug is -- it seems to me that it is just adding more boilerplate..</div><div><br></div><div>I added two new modules to URLT, namely URLT.Wai and URLT.Dispatch.</div>
<div><br></div><div>I think implemented your little blog demo twice. Once where I didn&#39;t use dispatch, and once were I did. The code for that is here:</div><div><br></div><div><a href="http://src.seereason.com/urlt/WaiExample.hs">http://src.seereason.com/urlt/WaiExample.hs</a></div>
<div><br></div><div>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&#39;t understand yet.</div>
<div><br></div><div>And instead of writing something short a straigt-forward like:</div><div><br></div><div> handleWai mkAbs fromAbs (mySite now)</div><div><br></div><div>I had to write the longer:</div><div><br></div><div>
 handleWai mkAbs fromAbs (dispatch (SiteArgs (BlogArgs now)))</div><div><br></div><div>And on the handler end, it hide useful information in the type signature and required more constructor matching. Instead of:</div><div>
<br></div><div><div>myBlog :: UTCTime -&gt; (BlogURL -&gt; String) -&gt; BlogURL -&gt; Application</div><div>myBlog now mkAbs BlogHome _request =</div><div><br></div><div>I have:</div><div><br></div><div><div>myBlogD :: BlogArgs -&gt; (BlogURL -&gt; String) -&gt; BlogURL -&gt; Application</div>
<div>myBlogD (BlogArgs now) mkAbs BlogHome _request =</div><div><br></div><div>In order to know the type of &#39;now&#39; I have to go look somewhere else. In &#39;myBlog&#39; it was right there in the type signature.</div>
<div><br></div><div>So, I guess I do not yet see the value of Dispatch. On the plus side, it doesn&#39;t seem like I have to use it if I don&#39;t like it. But I am curious if I am missing something useful here..</div><div>
<br></div><div>One advantage is that I can do:</div><div><br></div><div>:info Dispatch</div><div><br></div><div>in GHCi, and see all the Dispatch instances that are available. But I&#39;m not sure that really makes it worth the effort.</div>
<div><br></div><div>- jeremy</div><div><br></div><div>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.</div>
<div><br></div></div></div></div>