Using map result type
AA
duser at fastmail.com
Tue Dec 10 07:23:56 UTC 2019
On Sunday, 8 December 2019 at 01:43:43 UTC, mipri wrote:
> On Sunday, 8 December 2019 at 01:10:21 UTC, AA wrote:
>> [...]
>
> In general this is what you want to do with any kind of range
> code, because you're not working with definite types, but with
> types that have certain properties. And an advantage of this is
> that you can decide to do more or less efficient things at
> compile time based on additional properties of the types you're
> working with. Just open up phobos and look for 'static if':
>
> https://github.com/dlang/phobos/blob/master/std/algorithm/searching.d#L3858
>
> So if you you give minPos an array, it'll just foreach() over
> the array and return a slice. In which case minPos is exactly
> as efficient as the code you would've written by hand instead
> of using minPos, because it expands to that same code.
>
> And if you give minPos something else, it'll still work.
>
>> [...]
>
>> [...]
>
> Not really. Even if you try to use typeof() to get the
> (internal) type that std.alogorithm.map returns, you'll run
> into errors like
>
> Error: function x253.mapAccepter(MapResult!(__lambda5, int[])
> r) is not callable using argument types (MapResult!(__lambda1,
> int[]))
>
> when you try to use it.
>
>> [...]
>
> Certainly. Static reflection's what this kind of generic code
> is all about. See all the constraints in the std.algorithm pages
> in the library documentation? Just look at this one, randomly
> picked:
> https://dlang.org/phobos/std_algorithm_searching.html#.endsWith
>
> if (isBidirectionalRange!Range
> && (Needles.length > 1)
> && is(typeof(.endsWith!pred(doesThisEnd,
> withOneOfThese[0])) : bool)
> && is(typeof(.endsWith!pred(doesThisEnd,
> withOneOfThese[1..$])) : uint));
>
> So for your code:
>
> void mapAccepter(Range)(Range r)
> if (is(ElementType!Range == bool))
> {
> import std.array : array;
> import std.stdio : writeln;
>
> auto collected = r.array;
> writeln(collected);
> }
>
> Or if you do this often, maybe something like this would do:
>
> enum RangeOfBools(T) = is(ElementType!T == bool) &&
> isInputRange!T;
>
> void mapAccepter(Range)(Range r) if (RangeOfBools!Range)
> {
> import std.array : array;
> import std.stdio : writeln;
>
> auto collected = r.array;
> writeln(collected);
> }
Thanks for the detailed reply. So maybe it is just my perspective
coming from other languages that I was expecting a class i.e.
having some interface based way of dealing with the return type.
But I guess isInputRange checks for structural equality rather
than class and doesn't encode that into any interfaces in std
library normally?
Would the second solution of declaring a template constraint like
that be considering strange/out of place in D? e.g. do people
normally try and declare the template constraints on a function
or just rely on compile time failure from to instantiate template.
More information about the Digitalmars-d-learn
mailing list