Thank you!<div>Working implementation is even more than I&#39;ve expected.</div><div><br></div><div><br><br><div class="gmail_quote">2011/4/28 Felipe Almeida Lessa <span dir="ltr">&lt;<a href="mailto:felipe.lessa@gmail.com">felipe.lessa@gmail.com</a>&gt;</span><br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">On Thu, Apr 28, 2011 at 1:10 PM, Felipe Almeida Lessa<br>
<div class="im">&lt;<a href="mailto:felipe.lessa@gmail.com">felipe.lessa@gmail.com</a>&gt; wrote:<br>
&gt; On Thu, Apr 28, 2011 at 12:09 PM, Felipe Almeida Lessa<br>
&gt; &lt;<a href="mailto:felipe.lessa@gmail.com">felipe.lessa@gmail.com</a>&gt; wrote:<br>
&gt;&gt; I foresee one problem: what is the leftover of &#39;manyToOne xs&#39; if each<br>
&gt;&gt; x in xs needs different lengths of input?<br>
&gt;&gt;<br>
&gt;&gt; One possible untested-but-compiling solution:<br>
&gt; [snip]<br>
&gt;<br>
&gt; Like I said, that manyToOne implementation isn&#39;t very predictable<br>
&gt; about leftovers.  But I guess that if all your iteratees consume the<br>
&gt; same input OR if you don&#39;t care about leftovers, then it should be<br>
&gt; okay.<br>
<br>
</div>Sorry for replying to myself again. =)<br>
<br>
I think you can actually give predictable semantics to manyToOne:<br>
namely, the leftovers from the last iteratee are returned.  This new<br>
implementation should be better:<br>
<br>
import Data.Monoid (mappend)<br>
<div class="im">import qualified Data.Enumerator as E<br>
<br>
manyToOne :: Monad m =&gt; [E.Iteratee a m b] -&gt; E.Iteratee a m [b]<br>
</div>manyToOne is = E.Iteratee $ mapM E.runIteratee is &gt;&gt;=<br>
                            E.runIteratee . go<br>
    where<br>
      go [step]              = fmap (:[]) (E.returnI step)<br>
      go (E.Yield b _  : xs) = fmap (b:)  (go xs)<br>
      go (E.Error exc  : _)  = E.returnI (E.Error exc)<br>
      go (E.Continue f : xs) = E.continue $ go&#39; (E.Continue f : xs)<br>
      go []                  = return []<br>
<br>
      go&#39; xs stream = manyToOne $ feed xs<br>
        where<br>
          feed [E.Yield b s]       = [E.yield b (s `mappend` stream)]<br>
          feed (E.Continue f : ys) = f stream       : feed ys<br>
          feed (step         : ys) = E.returnI step : feed ys<br>
          feed []                  = []<br>
<br>
With the same test as before:<br>
<div class="im"><br>
*Main&gt; E.run $ E.enumList 1 [5 :: Int, 6, 7] E.$$ manyToOne [return 1,<br>
maybe 2 id `fmap` E.head, return 3, maybe 4 id `fmap` (E.head &gt;&gt;<br>
E.head)] &gt;&gt;= \xs -&gt; (,) xs `fmap` E.head<br>
Right ([1,5,3,6],Just 7)<br>
*Main&gt; E.run $ E.enumList 10 [5 :: Int, 6, 7] E.$$ manyToOne [return<br>
1, maybe 2 id `fmap` E.head, return 3, maybe 4 id `fmap` (E.head &gt;&gt;<br>
E.head)] &gt;&gt;= \xs -&gt; (,) xs `fmap` E.head<br>
</div>Right ([1,5,3,6],Just 7)<br>
<br>
When the last iteratee doesn&#39;t consume anything:<br>
<div class="im"><br>
*Main&gt; E.run $ E.enumList 1 [5 :: Int, 6, 7] E.$$ manyToOne [return 1,<br>
maybe 2 id `fmap` E.head, return 3, maybe 4 id `fmap` (E.head &gt;&gt;<br>
</div>E.head), return 10] &gt;&gt;= \xs -&gt; (,) xs `fmap` E.head<br>
Right ([1,5,3,6,10],Just 5)<br>
<div class="im">*Main&gt; E.run $ E.enumList 10 [5 :: Int, 6, 7] E.$$ manyToOne [return<br>
1, maybe 2 id `fmap` E.head, return 3, maybe 4 id `fmap` (E.head &gt;&gt;<br>
</div>E.head), return 10] &gt;&gt;= \xs -&gt; (,) xs `fmap` E.head<br>
Right ([1,5,3,6,10],Just 5)<br>
<br>
HTH,<br>
<br>
--<br>
<font color="#888888">Felipe.<br>
</font></blockquote></div><br></div>