<div dir="ltr"><br><div class="gmail_extra"><br><br><div class="gmail_quote">On Thu, Oct 31, 2013 at 8:59 PM, Craig Dillabaugh <span dir="ltr"><<a href="mailto:cdillaba@cg.scs.carleton.ca" target="_blank">cdillaba@cg.scs.carleton.ca</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><br>
</blockquote></blockquote>
<br>
Thanks, I will try both your, and Bearophile's ideas and see if I<br>
can figure out how they work.</blockquote><div><br></div><div><br></div><div>reduce takes a range and eagerly (that is, not lazily) builds a value from it. In your case, it builds the squared distance between two points. The returned value can be anything: a numerical value, but also another range, a complex object, an so on. As long as it can be built increasingly, you're good.</div>
<div><br></div><div>Given a range [a,b,c,..., z] and a binary function f, reduce!(f)([a,b,c,...]) calculates f(a,b), then f(f(a,b), c), up to f(... f( f( f(a,b),c), d), ...,z).</div><div><br></div><div>The only question is whether you give it a seed value, or if it takes the first range element as seed (f(seed, a), f(f(seed,a),b) and son on). std.algorithm.reduce provides both overloads.</div>
<div><br></div><div>Note the only thing you get is the final result, not the internal f(f(...'s applications.</div><div><br></div><div>If you want a sum:</div><div><br></div><div>reduce!( (result,elem) => result + elem )(range)</div>
<div><br></div><div>or</div><div><br></div><div><div>reduce!( (result,elem) => result + elem )(range, 0)</div></div><div><br></div><div>Sum of squares:</div><div><br></div><div><div>reduce!( (result, elem) => result + elem^^2 )(range, 0)</div>
</div><div><br></div><div>In your case, the basic element is a tuple, coming from zip. Access to the two elements is done with [0] or [1]. So:<br></div><div><br></div><div>reduce!( (result, elem) => result + (elem[0]-elem[1])^^2 )(zippedRange, 0)<br>
</div><div><br></div><div><br></div><div>Of course, it would be easy to write a small n-range reduce helper function, that takes n ranges and reduces them in parallel:</div><div><br></div><div><div>reduce!( (result, a, b) => result + (a-b)^^2 )(rangeA, rangeB, 0)<br>
</div></div><div><br></div><div>Note that reduce is a versatile function: you can duplicate filter and map functionalities with it. The only thing to remember is that, compared to other iteration algorithm/ranges, it's eager. Don't use it on an infinite range!</div>
<div><br></div><div><br></div><div>We could also have a slightly different version that lazily produces the intermediate results as a range. IIRC, it's called 'scan' in Haskell. It's sometimes interesting to have it: you can interrupt the ongoing calculation when the result is 'good enough', not waiting for the entire input range to be consumed.<br>
</div><div><br></div><div><br></div></div></div></div>