non empty slices

Alex via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Thu Jun 2 13:11:21 PDT 2016


On Thursday, 2 June 2016 at 16:21:03 UTC, ag0aep6g wrote:
> On 06/02/2016 05:16 PM, Alex wrote:
>
> 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.
Yes.

> * The branching in f is guided by the parameter types of f_impl 
> (could possibly be extracted, instead of being hardcoded 
> manually).
Yes! :)

>
> Tell me if I'm way off.
You totally hit the point!
The cool thing about the Algebraic is as I expected, that it 
doesn't change it's type... And the hard thing is, that I'm not 
used to its Empty, Many, ... things yet.
But the question remains how to keep this @nogc? I wonder at the 
line with peek... and why it is not just returning the value...


More information about the Digitalmars-d-learn mailing list