non empty slices
ag0aep6g via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Thu Jun 2 09:21:03 PDT 2016
On 06/02/2016 05:16 PM, Alex wrote:
> What I mean is: if there would be a possibility to use algebraic types
> here (or maybe some kind of template...), then my types would be able
> (maybe! did not seen anything similar yet...) to choose the proper
> methods for themselves automatically:
> As long as my type has a length > 1 it is handled as a range, if the
> range has the length=1 it is handled as a single element and not as a
> range, if the range has the length=0 it is handled as an absent element.
I may be getting what you're up to. Maybe not.
So we start with something like this (using arrays instead of arbitrary
ranges to keep things simple):
import std.stdio: writeln;
void main()
{
f([]);
f([1]);
f([1, 2]);
}
void f(int[] a)
{
if (a.length == 0) f_none(a);
else if (a.length == 1) f_one(a);
else f_many(a);
}
void f_none(int[] a)
{
writeln("nothing to see here");
}
void f_one(int[] a)
{
assert(a.length == 1);
writeln("exactly one: ", a[0]);
}
void f_many(int[] a)
{
assert(a.length >= 2);
writeln("at least two: ", a[0 .. 2]);
}
And instead you'd like something more like this:
import std.stdio: writeln;
import std.variant: Algebraic;
void main()
{
f([]);
f([1]);
f([1, 2]);
}
void f(int[] arr)
{
A a = arrayToA(arr);
foreach (T; A.AllowedTypes)
{
if (T* p = a.peek!T) f_impl(*p);
}
}
void f_impl(Empty e) { writeln("nothing to see here"); }
void f_impl(int a) { writeln("exactly one: ", a); }
void f_impl(Many!int a) { writeln("at least two: ", a[0 .. 2]); }
struct Empty {}
struct Many(T)
{
T[] arr;
alias arr this;
/* Somehow it's enforced here that arr.length >= 2. */
}
alias A = Algebraic!(Empty, int, Many!int);
A arrayToA(int[] a)
{
A result;
switch (a.length)
{
case 0: result = Empty.init; break;
case 1: result = a[0]; break;
default: result = Many!int(a);
}
return result;
}
And the advantages of it are:
* Don't need asserts in the different `f_impl`s.
* The branching in f is guided by the parameter types of f_impl (could
possibly be extracted, instead of being hardcoded manually).
Tell me if I'm way off.
More information about the Digitalmars-d-learn
mailing list