Using map result type
Meta
jared771 at gmail.com
Wed Dec 11 20:08:37 UTC 2019
On Sunday, 8 December 2019 at 01:10:21 UTC, AA wrote:
> I'd like to accept the return type of map. From some previous
> questions that I should accept a template?
> So for something like:
>
> ```
> void mapAccepter(Range)(Range r)
> {
> import std.array : array;
> import std.stdio : writeln;
>
> auto collected = r.array;
> writeln(collected);
> }
>
> void main()
> {
> import std.algorithm.iteration : map;
>
> int[] nums = [1, 2, 3];
> auto evenness = map!(n => n % 2 == 0)(nums);
> mapAccepter(evenness);
> }
> ```
> 1) Is there any way I can make `mapAccepter` not a templated
> function?
Yes (mostly, anyway), using the interfaces in
std.range.interfaces:
https://dlang.org/phobos/std_range_interfaces.html
import std.algorithm;
import std.range;
void mapAccepter(E)(InputRange!E r)
{
import std.array: array;
import std.stdio: writeln;
auto collected = r.array;
writeln(collected);
}
void main()
{
int[] nums = [1, 2, 3];
auto evenness = inputRangeObject(map!(n => n % 2 == 0)(nums));
mapAccepter(evenness);
}
`mapAccepter` still needs to be templated on the element type of
the range,
but there are ways to avoid that as well, if desired. I wouldn't
recommend it,
however, as it wouldn't be that useful in this case.
> 2) Is there any way if I need to make `mapAccepter` templated
> to constrain Range to be a range of booleans.
Yup, there are two ways that you you primarily do that. Either
constraining E in the template declaration, or adding a constraint
on the template. Generally option 2 is the more idiomatic D way.
Option 1: constrain E to be of type bool:
void mapAccepter(E: bool)(InputRange!E r);
OR
void mapAccepter(E)(InputRange!E r)
if (is(E == bool));
There's not much difference between these two, but the latter is
probably preferred.
Option 2: use std.traits and a template constraint:
void mapAccepter(E)(InputRange!E r)
if (is(ElementType!r == bool));
More information about the Digitalmars-d-learn
mailing list