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