On 06/02/2016 03:37 PM, Alex wrote:
The question is, how to define the same thing for ranges. What I started
with is:
import std.range : iota;
alias MrSlice = typeof(iota(M.init));
so far, so good. The MrSlice-thing is the analogy for Mr, as it can be
empty, as Mr can.
What I also need is the analogy for the M-thing. But how can I define a
slice, which is not-empty by definition?
A little terminology: "Slice" is not a synonym for "range". iota does
not return a slice, it returns a range. "Slice" is being used as a
synonym for "dynamic array" (Type[]), and in the context of the slicing
operator (expression[] or expression[a .. b]).
Now, for the actual question - how to define a range that is non-empty
by definition:
One of the range primitives is popFront. popFront removes one element
from the range. popFront cannot change the type of the range. So you
can't have a type that is a range, and is guaranteed not to be empty,
and can be emptied by calling popFront.
But you can have a type that is a range, is guaranteed not to be empty,
and *cannot* be emptied by calling popFront: an infinite range. That's a
range that never gets empty no matter how often popFront is called.
The library recognizes infinite ranges when you define `empty` like
this: `enum bool empty = false;`. There's
std.range.primitives.isInfinite [1] to check for them.
I guess that's not really what you're looking for. I don't think you can
otherwise statically check that a range isn't empty. You could probably
make a wrapper that checks once on construction, but that's still a
run-time check. And I don't see it being particularly useful, because
popFront is an essential parts of ranges.
[...]
I tried also something using Algebraic types with an underlying int, but
couldn't manage to append elements to something like:
alias List2 = Algebraic!(This[]);
or
alias List(Leaf) = Algebraic!(Leaf, This*);
The cool thing is, if the algebraic stuff works, it would potentially be
able to replace all four aliases altogether...
But a knock-out criteria is: the solution has to be @nogc
You've lost me there. I don't see how non-empty range and Algebraic connect.
[1] https://dlang.org/phobos/std_range_primitives.html#.isInfinite