Why does choose not work here
ag0aep6g
anonymous at example.com
Thu Aug 1 21:12:51 UTC 2019
On 01.08.19 22:23, Matt wrote:
> Version 4 does not work when PairedA.previous is null. I'd love to
> understand why.
>
[...]
>
> auto myFilter(R1, R2)(R1 a, R2 b)
> {
> import std.algorithm : filter, canFind;
> return a.filter!(c => b.canFind(c));
> }
>
> struct A
> {
> uint[] starts, stops;
>
> import std.range : ForwardRange, inputRangeObject;
> import std.typecons : Tuple;
> ForwardRange!(Tuple!(uint,uint)) intervalRange() @property
> {
> import std.algorithm : map;
> import std.range : zip;
> import std.typecons : tuple;
> return zip(starts,stops).map!(a =>
> tuple(a[0],a[1])).inputRangeObject;
> }
> }
>
> struct PairedA
> {
[...]
> //version 4
> auto uniqIntervals() @property
> {
> import std.range : choose;
> import std.algorithm : filter, canFind;
> return choose(previous is null,
> primary.intervalRange,
> primary.intervalRange
> .myFilter(previous.intervalRange));
> }
>
> A primary;
> A* previous;
> }
`choose`'s parameters aren't lazy. So the second argument is evaluated
even when `previous is null`. That means `intervalRange` is called on a
null `previous`. And that fails, of course, because `intervalRange`
can't access `starts` or `stops` when `this` is null.
More information about the Digitalmars-d-learn
mailing list