What is "FilterResult" type?

cym13 via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Wed Sep 9 01:29:19 PDT 2015


On Wednesday, 9 September 2015 at 07:19:06 UTC, Bahman Movaqar 
wrote:
> On Tuesday, 8 September 2015 at 18:45:33 UTC, Jonathan M Davis 
> wrote:
>> [...]
>
> @Jonathan, @cym13 and @Meta
> It's reasonable to use `auto`.  However there are times when 
> you need to pass the `auto` value to another function and the 
> receiving function needs to know the type of its input 
> arguments.
>
> In other news:
> Consider the following piece of code.  *Please note that I am 
> aware that the simple problem introduced can be solved in 
> several ways which are more efficient.*
>
>     immutable struct FooBar {
>       int x;
>       int y;
>     }
>     immutable(FooBar)[] foobars = [
>       FooBar(60, 100),
>       FooBar(8, 20),
>       FooBar(9, 15)
>     ];
>     int[] nums = [20, 40, 55];
>
>     //////////////////////////////////////////
>     // find FooBars which:
>     //   - x * y is greater than any `num`
>     //   - x and y are smaller than any `num`
>     //////////////////////////////////////////
>     auto result = reduce!(
>       (acc, num) => acc.filter!(
>         fb => (fb.x < num && fb.y < num) && (fb.x * fb.y > num)
>       )
>     )(foobars, nums);
>     //
>     assert(result[0].x == 9 && result[0].y == 15);
>
> This fails to compile with the following message:
>
>     Error: static assert  "Incompatible function/seed/element: 
> test.__unittestL40_4.__lambda1/immutable(FooBar)[]/int"
>     /usr/include/dmd/phobos/std/algorithm/iteration.d(2518):
>   instantiated from here: reduceImpl!(false, int[], 
> immutable(FooBar)[])
>     /usr/include/dmd/phobos/std/algorithm/iteration.d(2502):
>   instantiated from here: reducePreImpl!(int[], 
> immutable(FooBar)[]) test.d(56):        instantiated from here: 
> reduce!(immutable(FooBar)[], int[])
>
> The only way to make it work is `.array.idup` the output of 
> `filter`.  For example:
>
>     auto result = reduce!(
>       (acc, num) => acc.filter!(
>         fb => (fb.x < num && fb.y < num) && (fb.x * fb.y > num)
>       ).array.idup
>     )(foobars, nums);
>
> Honestly, I cannot comprehend anything out of this; why I had 
> to realise the lazy value and `idup` it for it to become usable 
> by `reduce`?
> Does this mean that I am simply missing something obvious?

You are using reduce in a weird way here... I find it normal to 
have to use weird internal tricks if you are trying weird things. 
The way I would have written it is:

auto result = foobars.filter!(fb => nums.all!(n => (fb.x * fb.y) 
 > n))
                      .filter!(fb => nums.all!(n => fb.x < n && 
fb.y < n));

Here you don't have any weird and completely unreadable reduce 
construct and don't have to realize the lazy check as 
std.algorithm.searching.all is lazy too.


More information about the Digitalmars-d-learn mailing list