<div class="gmail_quote"><div>At first I regarded this as simply a bug in the Iteratee.map definition, but like Ben, it&#39;s started to bother me a lot.  I think this is precisely the sort of issue a proper denotational semantics would fix.</div>
<div><br></div><div>Unfortunately the only general solution I see is to abandon chunking and work strictly element-wise.  I say unfortunately because my current best implementation is about 5 times slower than the main tree.  I&#39;m open to ideas.</div>
<div><br></div><div>John</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">From: Ben &lt;<a href="mailto:midfield@gmail.com">midfield@gmail.com</a>&gt;<br>

<br>
Sorry to be late coming into this conversation.....<br>
<br>
Something that has bothered me (which I have mentioned to John Lato<br>
privately) is that it is very easy to write non-compositional code due<br>
to the chunking.  For example, there is a standard function<br>
<br>
map :: (a -&gt; b) -&gt; Enumeratee a b c<br>
<br>
whose meaning I hope is clear : use the function to transform the type<br>
of a stream and pass it to an iteratee.  However last I checked the<br>
versions provided in both the iteratee and enumerator packages fail to<br>
satisfy the equation<br>
<br>
map f (it1 &gt;&gt; it2) == (map f it1) &gt;&gt; (map f it 2)<br>
<br>
because of chunking, essentially.  You can check this with f == id and<br>
it1 and it2 are head:<br>
<br>
let r = runIdentity . runIteratee<br>
<br>
runIdentity $ run $ enumList 10 [1..100] $ r $ joinI $ map id $ r (head &gt;&gt; head)<br>
--&gt; Right (Just 2)<br>
<br>
runIdentity $ run $ enumList 10 [1..100] $ r $ joinI $ (map id $ r<br>
head) &gt;&gt; (map id $ r head)<br>
--&gt; Right (Just 11)<br>
<br>
It is possible to fix this behavior, but it complicates the &quot;obvious&quot;<br>
definitions a lot.<br>
<br>
B<br>
<br>
On Wed, Sep 1, 2010 at 5:10 AM, Heinrich Apfelmus<br>
&lt;<a href="mailto:apfelmus@quantentunnel.de">apfelmus@quantentunnel.de</a>&gt; wrote:<br>
&gt; Tilo Wiklund wrote:<br>
&gt;&gt;<br>
&gt;&gt; Daniel Fischer wrote:<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; [...]<br>
&gt;&gt;&gt; Well, I just gave an example where one would want chunking for reasons<br>
&gt;&gt;&gt; other than performance. That iteratees don&#39;t provide the desired<br>
&gt;&gt;&gt; functionality is a different matter.<br>
&gt;&gt;&gt; [...]<br>
&gt;&gt;<br>
&gt;&gt; In the case of hashing, wouldn&#39;t it be more reasonable to consider<br>
&gt;&gt; iterators over streams of fixed (or at least predictable) sized chunks<br>
&gt;&gt; (where a set of chunks can themselves be chunked), with the chunking<br>
&gt;&gt; behaviour being given by another iteratee over the original stream?<br>
&gt;&gt;<br>
&gt;&gt; It seems to me that one of the major points of iteratees is to provide<br>
&gt;&gt; an abstraction from the kind of chunking irrelevant to the parsing<br>
&gt;&gt; logic, otherwise I fail to see any difference (at least relevant to<br>
&gt;&gt; chunking) to plain strict IO.<br>
&gt;<br>
&gt; I thought so, too, but I was informed[1] that iteratees are just a small<br>
&gt; step up the abstraction ladder. The difference compared to an ordinary file<br>
&gt;  Handle  is that you can now reuse one and the same iteratee for reading<br>
&gt; from a  String , for instance, without changing the source code of the<br>
&gt; iteratee.<br>
&gt;<br>
&gt; Furthermore, iteratees can be suspended, which facilities resource<br>
&gt; management like closing files handles after they&#39;ve been read.<br>
&gt;<br>
&gt;  [1]:<br>
&gt; <a href="http://www.reddit.com/r/haskell/comments/ar4wb/understanding_iteratees/c0j0f3r" target="_blank">http://www.reddit.com/r/haskell/comments/ar4wb/understanding_iteratees/c0j0f3r</a><br>
&gt;<br>
&gt;<br>
&gt;<br>
&gt; Regards,<br>
&gt; Heinrich Apfelmus<br>
&gt;<br>
&gt; --<br>
&gt; <a href="http://apfelmus.nfshost.com" target="_blank">http://apfelmus.nfshost.com</a><br>
&gt;<br>
&gt; _______________________________________________<br>
&gt; Haskell-Cafe mailing list<br>
&gt; <a href="mailto:Haskell-Cafe@haskell.org">Haskell-Cafe@haskell.org</a><br>
&gt; <a href="http://www.haskell.org/mailman/listinfo/haskell-cafe" target="_blank">http://www.haskell.org/mailman/listinfo/haskell-cafe</a><br>
&gt;<br><br>
</blockquote></div><br>