<div dir="ltr">I&#39;d mentioned in my previous email that I was concerned that &quot;consume&quot; would traverse the entire list for each new record pulled from the database. I&#39;ll try to start using the combinators instead; do get started with, it was easier to just use the raw datatypes to more easily see what was happening.<div>
<br></div><div>Would this version of consume perhaps be better:</div><div><br></div><div><div>consume :: Monad m =&gt; Iteratee e a m [a]</div><div>consume = liftI $ step id where</div><div>    step acc chunk =</div><div>
        case chunk of</div><div>            Chunks [] -&gt; Continue $ returnI . step acc</div><div>            Chunks xs -&gt; Continue $ returnI . (step $ acc . (xs ++))</div><div>            EOF -&gt; Yield (acc []) EOF</div>
<div><br></div><div>Michael<br><br><div class="gmail_quote">On Thu, Aug 19, 2010 at 8:40 AM, John Millikin <span dir="ltr">&lt;<a href="mailto:jmillikin@gmail.com">jmillikin@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;">
I&#39;m glad to hear you found it useful!<br>
<br>
For implementing selectList, have you considered using the &quot;consume&quot;<br>
iteratee? I suspect it would simplify your code to something like:<br>
<br>
selectList a b c d = do<br>
    res &lt;- run $ select a b c d ==&lt;&lt; consume<br>
    case res of<br>
        Left e -&gt; error e<br>
        Right x -&gt; return x<br>
<br>
You might also want to look at the iteratee combinators (returnI,<br>
yield, continue), which would reduce some boilerplate, eg:<br>
<br>
&quot;Iteratee $ return $ Continue k&quot; becomes &quot;continue k&quot;<br>
&quot;Iteratee $ return $ Yield x EOF&quot; becomes &quot;yield x EOF&quot;<br>
<div><div></div><div class="h5"><br>
On Wed, Aug 18, 2010 at 22:24, Michael Snoyman &lt;<a href="mailto:michael@snoyman.com">michael@snoyman.com</a>&gt; wrote:<br>
&gt; John,<br>
&gt; This package looks very promising. I used iteratee for the yaml package, but<br>
&gt; I had many of the concerns that you have mentioned below. Version 0.2 of<br>
&gt; persistent is going to have some form of an enumerator interface for getting<br>
&gt; the results of a query, and I eventually decided that iteratee was<br>
&gt; introducing too much complexity to be a good candidate. However, I was able<br>
&gt; to port the package[1] over to enumerator in about half an hour; I<br>
&gt; especially benefited from your example applications.<br>
&gt;<br>
&gt; The only concern that I had was the possible inefficiency of representing<br>
&gt; all chunks as a list. In the case of persistent, the enumerator will<br>
&gt; *always* generate a one-lengthed list, and the most common operation is<br>
&gt; selectList, which returns all results as a list. If I used your consume<br>
&gt; function, I believe there would be a *lot* of list traversals. Instead,<br>
&gt; selectList[2] uses ([a] -&gt; [a]) for building up the result internally. I<br>
&gt; haven&#39;t really thought the issue through fully, so I can recommend anything<br>
&gt; better. Perhaps more importantly, the simplification introduced by just<br>
&gt; dealing with lists is well received.<br>
&gt; Keep up the good work, I look forward to seeing more about enumerator.<br>
&gt; Michael<br>
&gt; [1] <a href="http://github.com/snoyberg/persistent/tree/enumerator" target="_blank">http://github.com/snoyberg/persistent/tree/enumerator</a><br>
&gt; [2] <a href="http://github.com/snoyberg/persistent/blob/enumerator/Database/Persist/Base.hs#L322" target="_blank">http://github.com/snoyberg/persistent/blob/enumerator/Database/Persist/Base.hs#L322</a><br>
</div></div></blockquote></div><br></div></div></div>