Option types and pattern matching.

TheFlyingFiddle via Digitalmars-d digitalmars-d at puremagic.com
Sat Oct 24 23:22:50 PDT 2015


On Sunday, 25 October 2015 at 05:45:15 UTC, Nerve wrote:
> On Sunday, 25 October 2015 at 05:05:47 UTC, Rikki Cattermole 
> wrote:
>> Since I have no idea what the difference between Some(_), None 
>> and default. I'll assume it's already doable.
>
> _ represents all existing values not matched. In this case, 
> Some(_) represents any integer value that is not 7. None 
> specifically matches the case where no value has been returned. 
> We are, in most languages, also able to unwrap the value:
>
> match x {
>     Some(7) => "Lucky number 7!",
>     Some(n) => "Not a lucky number: " ~ n,
>     None => "No value found"
> }

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);
}



More information about the Digitalmars-d mailing list