Option types and pattern matching.
TheFlyingFiddle via Digitalmars-d
digitalmars-d at puremagic.com
Mon Oct 26 07:13:19 PDT 2015
On Monday, 26 October 2015 at 11:40:09 UTC, Edmund Smith wrote:
> On Sunday, 25 October 2015 at 06:22:51 UTC, TheFlyingFiddle
> wrote:
> You could also emulate constant matching using default
> parameters (albeit with the restriction that they must be after
> any non-default/constant parameters), since the defaults form
> part of the function's type. I tried making something like this
> earlier this summer and it'd check that a given value was first
> equal to the default parameter and match if so, or match if
> there was no default parameter but the types matched.
>
> e.g.
> //template ma(tch/g)ic
>
> unittest
> {
> Algebraic!(string, int, double, MyStruct) v = 5;
> string s = v.match!(
> (string s = "") => "Empty string!",
> (string s) => s,
> (int i = 7) => "Lucky number 7",
> (int i = 0) => "Nil",
> (int i) => i.to!string,
> (double d) => d.to!string,
> (MyStruct m = MyStruct(15)) => "Special MyStruct value",
> (MyStruct m) => m.name, //
> () => "ooer");
> writeln(s);
> }
>
> It's a bit ugly overloading language features like this, but it
> makes the syntax a little prettier.
This does look nicer indeed.
>>Why not just use a value as an extra argument:
>>v.match!(
>> 7, (int i) => "Lucky number 7"
>>);
I like this you could go further with this to allow any number of
constants.
v.match!(
5, 7, i => "Was: " ~ i.to!string,
(int i) => "Was this: " ~ i.to!string);
Or for ranges.
v.match!(
MatchR!(1, 10), i => "Was: " ~ i.to!string, //Matches 1 .. 10
(int i) => "Was this: " ~ i.to!string);
> I'd really like to see proper pattern matching as a
> language-level feature however; for all the emulating it we can
> do in D, it's not very pretty or friendly and optimising it is
> harder since the language has no concept of pattern matching.
One could probably get something like this:
int i = 5;
string s = i.match!(
5, 7, n => "Five or seven",
MatchR!(10, 100), n => "Was between ten and a hundred",
(n) => "Was: " ~ n.to!string);
to fold into something like this:
void match(T...)(int i)
{
switch(i)
{
case 5: case 7: return (T[2])!int(i);
case 10: .. case 99: return (T[3])!int(i);
default: return (T[4])!int(i);
}
}
int i = 5;
string s = match!(/* lambdas and whatnot */), i);
With some template/ctfe and string mixings magic.
In-lining, constant folding etc could probably just reduce it to
the equvalent of:
int i = 5;
string s = "Five or seven";
(if there is really good constant folding :P)
It might however generate lot's of useless symbols in the
resulting code
making code size's larger.
> Things like Option (and other ADTs) are lovely, but really need
> good pattern matching to become worthwhile IMO (e.g. Java
> Optional<T> has a get() method that throws on empty, which
> undermines the main reason to use optional -
Another thing that has always bothered me with Optional<T> in
Java in addition to this is that the optional value itself might
be null. So to write robust code you first have to check against
null on the option value :P.
> Scala's Option is really nice on the other hand since you
> can/should pattern match).
Don't really see a point in an optional type if can access the
underlying
value without first checking if it's there.
More information about the Digitalmars-d
mailing list