Option types and pattern matching.

Nerve via Digitalmars-d digitalmars-d at puremagic.com
Sun Oct 25 07:43:21 PDT 2015


On Sunday, 25 October 2015 at 06:22:51 UTC, TheFlyingFiddle wrote:
> You can do something very similar to that. With slightly 
> different syntax.
>
> import std.traits;
> import std.conv;
> import std.variant;
> struct CMatch(T...) if(T.length == 1)
> {
>    alias U = typeof(T[0]);
>    static bool match(Variant v)
>    {
>       if(auto p = v.peek!U)
>          return *p == T[0];
>       return false;
>    }
> }
>
> auto ref match(Handlers...)(Variant v)
> {
>    foreach(handler; Handlers)
>    {
>       alias P = Parameters!handler;
>       static if(P.length == 1)
>       {
>          static if(isInstanceOf!(CMatch, P[0]))
>          {
> 	    if(P[0].match(v))
>                return handler(P[0].init);
>          }
>          else
>          {
>             if(auto p = v.peek!(P[0]))
>                return handler(*p);
>          }
>       }
>       else
>       {
>          return handler();
>       }
>    }
>
>    assert(false, "No matching pattern");
> }
>
> unittest
> {
>     Variant v = 5;
>     string s = v.match!(
> 	(CMatch!7) => "Lucky number seven",
> 	(int n)    => "Not a lucky number: " ~ n.to!string,
> 	()         => "No value found!");
>
>    writeln(s);
> }

That is actually freaking incredible. It evaluates to a value, 
unwraps values, matches against the None case...I guess the only 
thing it doesn't do is have compiler-enforced matching on all 
cases. Unless I'm just slow this morning and not thinking of 
other features a pattern match should have.


More information about the Digitalmars-d mailing list