On Tuesday, 8 September 2015 at 11:08:59 UTC, Bahman Movaqar
wrote:
However, I have made this a strict practice of mine to specify
the full signature of my public API. I suppose, if I want to
be pedantic, I have to realise the lazy value first and pass
the resulting array out. Is this correct?
If you _really_ want to specify the return type, you can import
std.range.interfaces[1] and use the appropriate return type
(e.g., InputRange!int, RandomAccessFinite!char, etc.) and then
append a `.inputRangeObject` to the end of your range chain.
Ex:
import std.algorithm;
import std.range;
InputRange!int doRangeyThings(R)(R r)
if (isInputRange!R)
{
return r.filter!(x => !(x & 1))
.map!(x => x * 2)
.inputRangeObject;
}
void main()
{
auto n = [1, 2, 3, 4];
auto m = n.doRangeyThings();
assert(is(typeof(m) == InputRange!int));
assert(m.equal([4, 8]));
}
You should use this sparingly, however. The types in
std.range.interfaces are interfaces that allow you to combine
ranges with runtime polymorphism, and you have to pay the
corresponding price for that, namely, you'll be hitting the GC
and the virtual functions entail a speed hit.
1. http://dlang.org/phobos/std_range_interfaces.html