<p>Have you already verified that stream fusion won't just do this for you?</p>
<div class="gmail_quote">On May 23, 2012 12:35 AM, "Evan Laforge" <<a href="mailto:qdunkan@gmail.com">qdunkan@gmail.com</a>> wrote:<br type="attribution"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
So I wanted to find the first index in a vector whose running sum is<br>
greater than a given number.<br>
<br>
The straightforward way is to create the running sum and then search:<br>
<br>
Vector.findIndex (>=target) (Vector.scanl' (+) 0 vector)<br>
<br>
But vectors are strict so it could do extra work, and what if I don't<br>
want to generate garbage? I could do it with a fold, but it would<br>
have to have the ability to abort early. Of course I could write such<br>
a fold myself using indexing:<br>
<br>
import qualified Data.Vector.Generic as Vector<br>
<br>
fold_abort :: (Vector.Vector v a) => (accum -> a -> Maybe accum) -> accum<br>
-> v a -> accum<br>
fold_abort f accum vec = go 0 accum<br>
where go i accum = maybe accum (go (i+1)) $ f accum =<< vec Vector.!? i<br>
<br>
find_before :: (Vector.Vector v a, Num a, Ord a) => a -> v a -> Int<br>
find_before n = fst . fold_abort go (0, 0)<br>
where<br>
go (i, total) a<br>
| total + a >= n = Nothing<br>
| otherwise = Just (i+1, total+a)<br>
<br>
So it's bigger and clunkier, but I would think it would be much more<br>
efficient (provided using Data.Vector.Generic won't inhibit inlining<br>
and unboxing). But I'm a bit surprised there isn't already something<br>
like fold_abort... or is there?<br>
<br>
_______________________________________________<br>
Haskell-Cafe mailing list<br>
<a href="mailto:Haskell-Cafe@haskell.org">Haskell-Cafe@haskell.org</a><br>
<a href="http://www.haskell.org/mailman/listinfo/haskell-cafe" target="_blank">http://www.haskell.org/mailman/listinfo/haskell-cafe</a><br>
</blockquote></div>