Working with ranges: mismatched function return type inference

Ali Çehreli via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Tue Oct 11 10:42:42 PDT 2016


On 10/11/2016 10:28 AM, TheFlyingFiddle wrote:
> On Tuesday, 11 October 2016 at 15:46:20 UTC, orip wrote:
>> On Tuesday, 11 October 2016 at 13:06:37 UTC, pineapple wrote:
>>> Rewrite `return chain(ints[0..5], ints[8..$]);` as `return ints[0..5]
>>> ~ ints[8..$];`
>>>
>>> The `chain` function doesn't return an array, it returns a
>>> lazily-evaluated sequence of an entirely different type from `int[]`.
>>
>> Of course it does! I would like the function to return an "input range
>> of int", no matter which one specifically. Is this possible?
>
> It is, but you will have to use an interface / class to achieve this
> behavior (or use some sort of polymorphic struct). Something like this
> will do the trick:
>
> import std.range;
> import std.stdio;
>
> interface IInputRange(T)
> {
>     bool empty();
>     T front();
>     void popFront();
> }
>
> final class InputRange(Range) if(isInputRange!Range)
>     : IInputRange!(ElementType!Range)
> {
>     Range r;
>     this(Range r)
>     {
>         this.r = r;
>     }
>
>     bool empty() { return r.empty; }
>     ElementType!Range front() { return r.front; }
>     void popFront() { r.popFront; }
> }
>
> auto inputRange(Range)(Range r)
> {
>     return new InputRange!Range(r);
> }
>
> IInputRange!int foo(int[] ints)
> {
>     import std.range;
>     if(ints.length > 10) {
>         return inputRange(chain(ints[0 .. 5], ints[8 .. $]));
>     } else {
>         return inputRange(ints);
>     }
> }
>
> void main()
> {
>     auto ir  = foo([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
>     auto ir2 = foo([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
>     writeln(ir);
>     writeln(ir2);
> }
>
>
>

Those interfaces already exist in Phobos: :)

   https://dlang.org/phobos/std_range_interfaces.html

auto foo(int[] ints) {
   import std.range;
   if (ints.length > 10) {
       return 
cast(RandomAccessFinite!int)inputRangeObject(chain(ints[0..5], ints[8..$]));
   } else {
       return cast(RandomAccessFinite!int)inputRangeObject(ints);
   }
}

void main() {
     import std.stdio;
     import std.range;
     import std.algorithm;
     writeln(foo([1, 2, 3]));
     writeln(foo(iota(20).array));
}

Ali


More information about the Digitalmars-d-learn mailing list