I have been looking around at possibly making a Browser module for Network.HTTP.Conduit on top of Control.Monad.State. I came across this roadbump:<div><br></div><div>In order to implement redirection following, client code must call &#39;http&#39; with a redirection count of 0. If there is a redirect, &#39;http&#39; will throw an exception. In order to catch this exception and continue on with the redirection chain, the &#39;catch&#39; function must be called. The problem is that the &#39;catch&#39; function has a type of (catch :: Exception e =&gt; IO a -&gt; (e -&gt; IO a) -&gt; IO a) which means that it can only be used in the IO monad. A call to &#39;http&#39; inside the first argument of &#39;catch&#39; must be wrapped in a &#39;runResourceT&#39;</div>

<div><br></div><div>This has a couple implications:</div><div><ul><li>The catch function cannot yield a Source, because any connections which &#39;http&#39; opened will have to be immediately closed as soon as control reaches the &#39;catch&#39; function (because of the runResourceT). The only way around this is to put the bind inside the catch block with some default sink, but this loses all of the constant-memory benefits of using a conduit in the first place.</li>

<li>The function that will be calling &#39;catch&#39; operates as a State monad. Cookie state must be updated both before and after making the request (both inside the &#39;catch&#39; block and outside). I could pass around an updated cookie jar out of the IO monad as an extra entry in a tuple, but this defeats the purpose of using a State monad in the first place. This kind of programming is very ugly.</li>

</ul>I see two solutions to these problems:<br></div><div><ul><li>Make &#39;http&#39; not throw a StatusCodeException if the _original_ redirection count = 0</li><li>Make my internal module call the un-exported &#39;httpRaw&#39; function. This has the problem that it doen&#39;t solve the problem for anyone else trying to use http-conduit; it only solves the problem for me. Perhaps this could be alleviated by exporting httpRaw.</li>

</ul>What do you think?</div><div>--Myles</div><div><br></div><div><div class="gmail_quote">On Tue, Feb 7, 2012 at 12:35 AM, Myles C. Maxfield <span dir="ltr">&lt;<a href="mailto:myles.maxfield@gmail.com">myles.maxfield@gmail.com</a>&gt;</span> wrote:<br>

<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Alright. I&#39;ll issue another pull request to you when it&#39;s done (expect in a couple weeks).<div><br></div><div>
Thanks for your input so far, Aristid and Michael.</div>
<div><br></div><div>@Chris Wong: Do you want to talk about the Suffix List stuff some time?</div><span class="HOEnZb"><font color="#888888">
<div><br></div></font></span><div><span class="HOEnZb"><font color="#888888">--Myles</font></span><div><div class="h5"><br><br><div class="gmail_quote">On Mon, Feb 6, 2012 at 10:14 PM, Michael Snoyman <span dir="ltr">&lt;<a href="mailto:michael@snoyman.com" target="_blank">michael@snoyman.com</a>&gt;</span> wrote:<br>

<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+1<br>
<div><div><br>
On Mon, Feb 6, 2012 at 11:16 PM, Aristid Breitkreuz<br>
&lt;<a href="mailto:aristidb@googlemail.com" target="_blank">aristidb@googlemail.com</a>&gt; wrote:<br>
&gt; I would say: if it adds no package dependencies, put it right in.<br>
&gt;<br>
&gt; Aristid<br>
&gt;<br>
&gt; Am 06.02.2012 22:09 schrieb &quot;Myles C. Maxfield&quot; &lt;<a href="mailto:myles.maxfield@gmail.com" target="_blank">myles.maxfield@gmail.com</a>&gt;:<br>
&gt;&gt;<br>
&gt;&gt; After all these commits have been flying around, I have yet another<br>
&gt;&gt; question:<br>
&gt;&gt;<br>
&gt;&gt; the &#39;HTTP&#39; package defines Network.Browser which is a State monad which<br>
&gt;&gt; keeps state about a &quot;browser&quot; (i.e. a cookie jar, a proxy, redirection<br>
&gt;&gt; parameters, etc.) It would be pretty straightforward to implement this kind<br>
&gt;&gt; of functionality on top of http-conduit.<br>
&gt;&gt;<br>
&gt;&gt; I was originally going to do it and release it as its own package, but it<br>
&gt;&gt; may be beneficial to add such a module to the existing http-conduit package.<br>
&gt;&gt; Should I add it in to the existing package, or release it as its own<br>
&gt;&gt; package?<br>
&gt;&gt;<br>
&gt;&gt; --Myles<br>
&gt;&gt;<br>
&gt;&gt; On Mon, Feb 6, 2012 at 12:15 AM, Michael Snoyman &lt;<a href="mailto:michael@snoyman.com" target="_blank">michael@snoyman.com</a>&gt;<br>
&gt;&gt; wrote:<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; Just an FYI for everyone: Myles sent an (incredibly thorough) pull<br>
&gt;&gt;&gt; request to handle cookies:<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; <a href="https://github.com/snoyberg/http-conduit/pull/13" target="_blank">https://github.com/snoyberg/http-conduit/pull/13</a><br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; Thanks!<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; On Sun, Feb 5, 2012 at 8:20 AM, Myles C. Maxfield<br>
&gt;&gt;&gt; &lt;<a href="mailto:myles.maxfield@gmail.com" target="_blank">myles.maxfield@gmail.com</a>&gt; wrote:<br>
&gt;&gt;&gt; &gt; 1. The spec defines a grammar for the attributes. They&#39;re in uppercase.<br>
&gt;&gt;&gt; &gt; 2. Yes - 1.3 is the first version that lists DiffTime as an instance of<br>
&gt;&gt;&gt; &gt; RealFrac (so I can use the &#39;floor&#39; function to pull out the number of<br>
&gt;&gt;&gt; &gt; seconds to render it)<br>
&gt;&gt;&gt; &gt; 3. I&#39;ll see what I can do.<br>
&gt;&gt;&gt; &gt;<br>
&gt;&gt;&gt; &gt; --Myles<br>
&gt;&gt;&gt; &gt;<br>
&gt;&gt;&gt; &gt;<br>
&gt;&gt;&gt; &gt; On Sat, Feb 4, 2012 at 9:06 PM, Michael Snoyman &lt;<a href="mailto:michael@snoyman.com" target="_blank">michael@snoyman.com</a>&gt;<br>
&gt;&gt;&gt; &gt; wrote:<br>
&gt;&gt;&gt; &gt;&gt;<br>
&gt;&gt;&gt; &gt;&gt; Looks good, a few questions/requests:<br>
&gt;&gt;&gt; &gt;&gt;<br>
&gt;&gt;&gt; &gt;&gt; 1. Is there a reason to upper-case all the attributes?<br>
&gt;&gt;&gt; &gt;&gt; 2. Is the time &gt;= 1.3 a requirements? Because that can cause a lot of<br>
&gt;&gt;&gt; &gt;&gt; trouble for people.<br>
&gt;&gt;&gt; &gt;&gt; 3. Can you send the patch as a Github pull request? It&#39;s easier to<br>
&gt;&gt;&gt; &gt;&gt; track that way.<br>
&gt;&gt;&gt; &gt;&gt;<br>
&gt;&gt;&gt; &gt;&gt; Michael<br>
&gt;&gt;&gt; &gt;&gt;<br>
&gt;&gt;&gt; &gt;&gt; On Sat, Feb 4, 2012 at 1:21 AM, Myles C. Maxfield<br>
&gt;&gt;&gt; &gt;&gt; &lt;<a href="mailto:myles.maxfield@gmail.com" target="_blank">myles.maxfield@gmail.com</a>&gt; wrote:<br>
&gt;&gt;&gt; &gt;&gt; &gt; Here is the patch to Web.Cookie. I didn&#39;t modify the tests at all<br>
&gt;&gt;&gt; &gt;&gt; &gt; because<br>
&gt;&gt;&gt; &gt;&gt; &gt; they were already broken - they looked like they hadn&#39;t been updated<br>
&gt;&gt;&gt; &gt;&gt; &gt; since<br>
&gt;&gt;&gt; &gt;&gt; &gt; SetCookie only had 5 parameters. I did verify by hand that the patch<br>
&gt;&gt;&gt; &gt;&gt; &gt; works,<br>
&gt;&gt;&gt; &gt;&gt; &gt; though.<br>
&gt;&gt;&gt; &gt;&gt; &gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt; Thanks,<br>
&gt;&gt;&gt; &gt;&gt; &gt; Myles<br>
&gt;&gt;&gt; &gt;&gt; &gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt; On Thu, Feb 2, 2012 at 11:26 PM, Myles C. Maxfield<br>
&gt;&gt;&gt; &gt;&gt; &gt; &lt;<a href="mailto:myles.maxfield@gmail.com" target="_blank">myles.maxfield@gmail.com</a>&gt; wrote:<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt; Alright, I&#39;ll make a small patch that adds 2 fields to SetCookie:<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt; setCookieMaxAge :: Maybe DiffTime<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt; setCookieSecureOnly :: Bool<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt; I&#39;ve also gotten started on those cookie functions. I&#39;m currently<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt; writing<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt; tests for them.<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt; @Chris: The best advice I can give is that Chrome (what I&#39;m using<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt; as a<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt; source on all this) has the data baked into a .cc file. However,<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt; they<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt; have<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt; directions in a README and a script which will parse the list and<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt; generate<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt; that source file. I recommend doing this. That way, the Haskell<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt; module<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt; would<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt; have 2 source files: one file that reads the list and generates the<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt; second<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt; file, which is a very large source file that contains each element<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt; in<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt; the<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt; list. The list should export `elem`-type queries. I&#39;m not quite<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt; sure<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt; how to<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt; handle wildcards that appear in the list - that part is up to you.<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt; Thanks<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt; for helping out with this :]<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt; --Myles<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt; On Thu, Feb 2, 2012 at 10:53 PM, Michael Snoyman<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt; &lt;<a href="mailto:michael@snoyman.com" target="_blank">michael@snoyman.com</a>&gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt; wrote:<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; Looks good to me too. I agree with Aristid: let&#39;s make the change<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; to<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; cookie itself. Do you want to send a pull request? I&#39;m also<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; considering making the SetCookie constructor hidden like we have<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; for<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; Request, so that if in the future we realize we need to add some<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; other<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; settings, it doesn&#39;t break the API.<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; Chris: I would recommend compiling it into the module. Best bet<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; would<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; likely being converting the source file to Haskell source.<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; Michael<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; On Fri, Feb 3, 2012 at 6:32 AM, Myles C. Maxfield<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &lt;<a href="mailto:myles.maxfield@gmail.com" target="_blank">myles.maxfield@gmail.com</a>&gt; wrote:<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; Alright. After reading the spec, I have these questions /<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; concerns:<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; The spec supports the &quot;Max-Age&quot; cookie attribute, which<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; Web.Cookies<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; doesn&#39;t.<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; I see two possible solutions to this. The first is to have<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; parseSetCookie<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; take a UTCTime as an argument which will represent the current<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; time<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; so<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; it<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; can populate the setCookieExpires field by adding the Max-Age<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; attribute<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; to<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; the current time. Alternatively, that function can return an IO<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; SetCookie so<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; it can ask for the current time by itself (which I think is<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; inferior<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; to<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; taking the current time as an argument). Note that the spec says<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; to<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; prefer<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; Max-Age over Expires.<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; Add a field to SetCookie of type Maybe DiffTime which represents<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; the<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; Max-Age<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; attribute<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; Cookie code should be aware of the Public Suffix List as a part<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; of<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; its<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; domain verification. The cookie code only needs to be able to<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; tell<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; if a<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; specific string is in the list (W.Ascii -&gt; Bool)<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; I propose making an entirely unrelated package,<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; public-suffix-list,<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; with a<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; module Network.PublicSuffixList, which will expose this<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; function, as<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; well as<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; functions about parsing the list itself. Thoughts?<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; Web.Cookie doesn&#39;t have a &quot;secure-only&quot; attribute. Adding one in<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; is<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; straightforward enough.<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; The spec describes cookies as a property of HTTP, not of the<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; World<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; Wide<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; Web.<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; Perhaps &quot;Web.Cookie&quot; should be renamed? Just a thought; it<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; doesn&#39;t<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; really<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; matter to me.<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; As for Network.HTTP.Conduit.Cookie, the spec describes in<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; section<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; 5.3<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; &quot;Storage Model&quot; what fields a Cookie has. Here is my proposal<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; for<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; the<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; functions it will expose:<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; receiveSetCookie :: SetCookie -&gt; Req.Request m -&gt; UTCTime -&gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; Bool -&gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; CookieJar -&gt; CookieJar<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; Runs the algorithm described in section 5.3 &quot;Storage Model&quot;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; The UTCTime is the current-time, the Bool is whether or not the<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; caller<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; is an<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; HTTP-based API (as opposed to JavaScript or anything else)<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; updateCookieJar :: Res.Response a -&gt; Req.Request m -&gt; UTCTime -&gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; CookieJar<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; -&gt; (CookieJar, Res.Response a)<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; Applies &quot;receiveSetCookie&quot; to a Response. The output CookieJar<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; is<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; stripped<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; of any Set-Cookie headers.<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; Specifies &quot;True&quot; for the Bool in receiveSetCookie<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; computeCookieString :: Req.Request m -&gt; CookieJar -&gt; UTCTime -&gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; Bool<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; -&gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; (W.Ascii, CookieJar)<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; Runs the algorithm described in section 5.4 &quot;The Cookie Header&quot;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; The UTCTime and Bool are the same as in receiveSetCookie<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; insertCookiesIntoRequest :: Req.Request m -&gt; CookieJar -&gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; UTCTime -&gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; (Req.Request m, CookieJar)<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; Applies &quot;computeCookieString&quot; to a Request. The output cookie<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; jar<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; has<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; updated last-accessed-times.<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; Specifies &quot;True&quot; for the Bool in computeCookieString<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; evictExpiredCookies :: CookieJar -&gt; UTCTime -&gt; CookieJar<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; Runs the algorithm described in the last part of section 5.3<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; &quot;Storage<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; Model&quot;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; This will make the relevant part of &#39;http&#39; look like:<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;     go count req&#39;&#39; cookie_jar&#39;&#39; = do<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;         now &lt;- liftIO $ getCurrentTime<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;         let (req&#39;, cookie_jar&#39;) = insertCookiesIntoRequest req&#39;&#39;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; (evictExpiredCookies cookie_jar&#39;&#39; now) now<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;         res&#39; &lt;- httpRaw req&#39; manager<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;         let (cookie_jar, res) = updateCookieJar res&#39; req&#39; now<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; cookie_jar&#39;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;         case getRedirectedRequest req&#39; (responseHeaders res)<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; (W.statusCode<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; (statusCode res)) of<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;             Just req -&gt; go (count - 1) req cookie_jar<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;             Nothing -&gt; return res<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; I plan to not allow for a user-supplied cookieFilter function.<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; If<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; they<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; want<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; that functionality, they can re-implement the<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; redirection-following<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; logic.<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; Any thoughts on any of this?<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; Thanks,<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; Myles<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; On Wed, Feb 1, 2012 at 5:19 PM, Myles C. Maxfield<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; &lt;<a href="mailto:myles.maxfield@gmail.com" target="_blank">myles.maxfield@gmail.com</a>&gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt; wrote:<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt; Nope. I&#39;m not. The RFC is very explicit about how to handle<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt; cookies.<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt; As<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt; soon as I&#39;m finished making sense of it (in terms of Haskell)<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt; I&#39;ll<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt; send<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt; another proposal email.<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt; On Feb 1, 2012 3:25 AM, &quot;Michael Snoyman&quot; &lt;<a href="mailto:michael@snoyman.com" target="_blank">michael@snoyman.com</a>&gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt; wrote:<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; You mean you&#39;re *not* making this proposal?<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; On Wed, Feb 1, 2012 at 7:30 AM, Myles C. Maxfield<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &lt;<a href="mailto:myles.maxfield@gmail.com" target="_blank">myles.maxfield@gmail.com</a>&gt; wrote:<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt; Well, this is embarrassing. Please disregard my previous<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt; email.<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt; I<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt; should<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt; learn to read the RFC *before* submitting proposals.<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt; --Myles<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt; On Tue, Jan 31, 2012 at 6:37 PM, Myles C. Maxfield<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt; &lt;<a href="mailto:myles.maxfield@gmail.com" target="_blank">myles.maxfield@gmail.com</a>&gt; wrote:<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; Here are my initial ideas about supporting cookies. Note<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; that<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; I&#39;m<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; using<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; Chrome for ideas since it&#39;s open source.<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; Network/HTTP/Conduit/Cookies.hs file<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; Exporting the following symbols:<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; type StuffedCookie = SetCookie<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; A regular SetCookie can have Nothing for its Domain and<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; Path<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; attributes. A<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; StuffedCookie has to have these fields set.<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; type CookieJar = [StuffedCookie]<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; Chrome&#39;s cookie jar is implemented as (the C++ equivalent<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; of)<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; Map<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; W.Ascii<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; StuffedCookie. The key is the &quot;eTLD+1&quot; of the domain, so<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; lookups<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; for<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; all<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; cookies for a given domain are fast.<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; I think I&#39;ll stay with just a list of StuffedCookies just<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; to<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; keep<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; it<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; simple. Perhaps a later revision can implement the faster<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; map.<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; getRelevantCookies :: Request m -&gt; CookieJar -&gt; UTCTime -&gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; (CookieJar,<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; Cookies)<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; Gets all the cookies from the cookie jar that should be set<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; for<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; the<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; given<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; Request.<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; The time argument is whatever &quot;now&quot; is (it&#39;s pulled out of<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; the<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; function so<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; the function can remain pure and easily testable)<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; The function will also remove expired cookies from the<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; cookie<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; jar<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; (given<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; what &quot;now&quot; is) and return the filtered cookie jar<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; putRelevantCookies :: Request m -&gt; CookieJar -&gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; [StuffedCookie]<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; -&gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; CookieJar<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; Insert cookies from a server response into the cookie jar.<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; The first argument is only used for checking to see which<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; cookies<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; are<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; valid (which cookies match the requested domain, etc, so<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; <a href="http://site1.com" target="_blank">site1.com</a><br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; can&#39;t set<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; a cookie for <a href="http://site2.com" target="_blank">site2.com</a>)<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; stuffCookie :: Request m -&gt; SetCookie -&gt; StuffedCookie<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; If the SetCookie&#39;s fields are Nothing, fill them in given<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; the<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; Request<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; from<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; which it originated<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; getCookies :: Response a -&gt; ([SetCookie], Response a)<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; Pull cookies out of a server response. Return the response<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; with<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; the<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; Set-Cookie headers filtered out<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; putCookies :: Request a -&gt; Cookies -&gt; Request a<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; A wrapper around renderCookies. Inserts some cookies into a<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; request.<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; Doesn&#39;t overwrite cookies that are already set in the<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; request<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; These functions will be exported from Network.HTTP.Conduit<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; as<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; well, so<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; callers can use them to re-implement redirection chains<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; I won&#39;t implement a cookie filtering function (like what<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; Network.Browser<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; has)<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; If you want to have arbitrary handling of cookies,<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; re-implement<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; redirection following. It&#39;s not very difficult if you use<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; the<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; API<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; provided,<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; and the &#39;http&#39; function is open source so you can use that<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; as a<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; reference.<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; I will implement the functions according to RFC 6265<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; I will also need to write the following functions. Should<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; they<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; also be<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; exported?<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; canonicalizeDomain :: W.Ascii -&gt; W.Ascii<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; turns &quot;..a.b.c..d.com...&quot; to &quot;<a href="http://a.b.c.d.com" target="_blank">a.b.c.d.com</a>&quot;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; Technically necessary for domain matching (Chrome does it)<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; Perhaps unnecessary for a first pass? Perhaps we can trust<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; users<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; for<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; now?<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; domainMatches :: W.Ascii -&gt; W.Ascii -&gt; Maybe W.Ascii<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; Does the first domain match against the second domain?<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; If so, return the prefix of the first that isn&#39;t in the<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; second<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; pathMatches :: W.Ascii -&gt; W.Ascii -&gt; Bool<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; Do the paths match?<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; In order to implement domain matching, I have to have<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; knowledge<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; of<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; the Public Suffix List so I know that<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; <a href="http://sub1.sub2.pvt.k12.wy.us" target="_blank">sub1.sub2.pvt.k12.wy.us</a><br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; can<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; set<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; a<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; cookie for <a href="http://sub2.pvt.k12.wy.us" target="_blank">sub2.pvt.k12.wy.us</a> but not for <a href="http://k12.wy.us" target="_blank">k12.wy.us</a><br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; (because<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; <a href="http://pvt.k12.wy.us" target="_blank">pvt.k12.wy.us</a><br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; is a &quot;suffix&quot;). There are a variety of ways to implement<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; this.<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; As far as I can tell, Chrome does it by using a script<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; (which a<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; human<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; periodically runs) which parses the list at creates a .cc<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; file<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; that is<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; included in the build.<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; I might be wrong about the execution of the script; it<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; might be<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; a<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; build<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; step. If it is a build step, however, it is suspicious that<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; a<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; build<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; target<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; would try to download a file...<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; Any more elegant ideas?<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; Feedback on any/all of the above would be very helpful<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; before I<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; go<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; off<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; into the weeds on this project.<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; Thanks,<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; Myles C. Maxfield<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; On Sat, Jan 28, 2012 at 8:17 PM, Michael Snoyman<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; &lt;<a href="mailto:michael@snoyman.com" target="_blank">michael@snoyman.com</a>&gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; wrote:<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; Thanks, looks great! I&#39;ve merged it into the Github tree.<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; On Sat, Jan 28, 2012 at 8:36 PM, Myles C. Maxfield<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &lt;<a href="mailto:myles.maxfield@gmail.com" target="_blank">myles.maxfield@gmail.com</a>&gt; wrote:<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt; Ah, yes, you&#39;re completely right. I completely agree<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt; that<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt; moving<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt; the<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt; function into the Maybe monad increases readability.<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt; This<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt; kind<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt; of<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt; function<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt; is what the Maybe monad was designed for.<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt; Here is a revised patch.<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt; On Sat, Jan 28, 2012 at 8:28 AM, Michael Snoyman<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt; &lt;<a href="mailto:michael@snoyman.com" target="_blank">michael@snoyman.com</a>&gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt; wrote:<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; On Sat, Jan 28, 2012 at 1:20 AM, Myles C. Maxfield<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; &lt;<a href="mailto:myles.maxfield@gmail.com" target="_blank">myles.maxfield@gmail.com</a>&gt; wrote:<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; &gt; the fromJust should never fail, beceause of the guard<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; &gt; statement:<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; &gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; &gt;     | 300 &lt;= code &amp;&amp; code &lt; 400 &amp;&amp; isJust l&#39;&#39; &amp;&amp;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; &gt; isJust<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; &gt; l&#39; =<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; &gt; Just $<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; &gt; req<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; &gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; &gt; Because of the order of the &amp;&amp; operators, it will<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; &gt; only<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; &gt; evaluate<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; &gt; fromJust<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; &gt; after it makes sure that the argument isJust. That<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; &gt; function<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; &gt; in<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; &gt; particular<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; &gt; shouldn&#39;t throw any exceptions - it should only<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; &gt; return<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; &gt; Nothing.<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; &gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; &gt; Knowing that, I don&#39;t quite think I understand what<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; &gt; your<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; &gt; concern<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; &gt; is.<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; &gt; Can<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; &gt; you<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; &gt; elaborate?<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; You&#39;re right, but I had to squint really hard to prove<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; to<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; myself<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; that<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; you&#39;re right. That&#39;s the kind of code that could easily<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; be<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; broken<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; in<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; future updates by an unwitting maintainer (e.g., me).<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; To<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; protect<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; the<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; world from me, I&#39;d prefer if the code didn&#39;t have the<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; fromJust.<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; This<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; might be a good place to leverage the Monad instance of<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; Maybe.<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt; Michael<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;&gt; &gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;&gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;<br>
&gt;&gt;&gt; &gt;<br>
&gt;&gt;&gt; &gt;<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt; _______________________________________________<br>
&gt;&gt; Haskell-Cafe mailing list<br>
&gt;&gt; <a href="mailto:Haskell-Cafe@haskell.org" target="_blank">Haskell-Cafe@haskell.org</a><br>
&gt;&gt; <a href="http://www.haskell.org/mailman/listinfo/haskell-cafe" target="_blank">http://www.haskell.org/mailman/listinfo/haskell-cafe</a><br>
&gt;&gt;<br>
&gt;<br>
</div></div></blockquote></div><br></div></div></div>
</blockquote></div><br></div>