Thread overview | |||||||||
---|---|---|---|---|---|---|---|---|---|
|
April 21, 2015 Structural exhaustive matching | ||||
---|---|---|---|---|
| ||||
What's the best equivalent to Rust's structural enum/pattern (match)ing? Is it also possible to enforce exhaustive matches? Basically, I'm curious on what the best way to do ADTs in D. |
April 21, 2015 Re: Structural exhaustive matching | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jadbox | Jadbox:
> I'm curious on what the best way to do ADTs in D.
Sometimes there's no best way, there are several alternative ways with different tradeoffs. D isn't a functional language and there's no really good way to do ADTs in D. You can use plus a "final switch". Or you can use Algebraic from Phobos. Sometimes you can use another Phobos function that simulates an improved switch. Or often you can just give up at using ADTs in D and use what other solutions D offers you (like OOP).
Bye,
bearophile
|
April 21, 2015 Re: Structural exhaustive matching | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jadbox | On Tuesday, 21 April 2015 at 15:36:28 UTC, Jadbox wrote:
> What's the best equivalent to Rust's structural enum/pattern (match)ing? Is it also possible to enforce exhaustive matches? Basically, I'm curious on what the best way to do ADTs in D.
D's ADTs are in std.variant, the equivalent of matching is the .visit property AFAIK
|
April 21, 2015 Re: Structural exhaustive matching | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jadbox | On Tue, 21 Apr 2015 15:36:27 +0000, Jadbox wrote:
> What's the best equivalent to Rust's structural enum/pattern (match)ing?
> Is it also possible to enforce exhaustive matches?
> Basically, I'm curious on what the best way to do ADTs in D.
std.variant.Algebraic implements ADTs:
import std.variant, std.string;
struct Foo { ... }
alias A = Algebraic!(int, double, Foo);
A a = 1;
// std.variant.visit enforces that all possible types are handled, so this
// is an error:
auto res = a.visit!(
(int x) => format("Got an int: %s", x),
(double x) => format("Got a double: %s", x),
(Foo x) => "Got a Foo"
);
You can also dispatch to a function with the appropriate overloads/ template instantiations like so:
foreach (T; A.AllowedTypes)
if (a.type is typeid(T))
myfunc(a.get!T);
This also exhaustively guarantees that myfunc can be called with all possible types of a.
|
April 21, 2015 Re: Structural exhaustive matching | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jadbox | On 2015-04-21 17:36, Jadbox wrote: > What's the best equivalent to Rust's structural enum/pattern (match)ing? > Is it also possible to enforce exhaustive matches? Basically, I'm > curious on what the best way to do ADTs in D. There's something call "castSwitch" [1], perhaps not what you're looking for. [1] http://dlang.org/phobos/std_algorithm_comparison.html#.castSwitch -- /Jacob Carlborg |
April 22, 2015 Re: Structural exhaustive matching | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jadbox | On Tuesday, 21 April 2015 at 15:36:28 UTC, Jadbox wrote:
> What's the best equivalent to Rust's structural enum/pattern (match)ing? Is it also possible to enforce exhaustive matches? Basically, I'm curious on what the best way to do ADTs in D.
If it needs to be really fast, use final switch on the tag of a discriminated union.
enum Tag { A, B, C }
struct Val
{
Tag tag;
union
{
A a;
B b;
C c;
}
}
void too(Val val)
{
final switch (val.tag)
{
case Tag.A: writeln(val.a); break;
case Tag.B: writeln(val.b); break;
case Tag.C: writeln(val.c); break;
}
}
|
April 22, 2015 Re: Structural exhaustive matching | ||||
---|---|---|---|---|
| ||||
Posted in reply to Martin Nowak | On Wednesday, 22 April 2015 at 04:54:39 UTC, Martin Nowak wrote:
> On Tuesday, 21 April 2015 at 15:36:28 UTC, Jadbox wrote:
>> What's the best equivalent to Rust's structural enum/pattern (match)ing? Is it also possible to enforce exhaustive matches? Basically, I'm curious on what the best way to do ADTs in D.
>
> If it needs to be really fast, use final switch on the tag of a discriminated union.
>
> enum Tag { A, B, C }
> struct Val
> {
> Tag tag;
> union
> {
> A a;
> B b;
> C c;
> }
> }
>
> void too(Val val)
> {
> final switch (val.tag)
> {
> case Tag.A: writeln(val.a); break;
> case Tag.B: writeln(val.b); break;
> case Tag.C: writeln(val.c); break;
> }
> }
there's no reason this should be faster than Algebraic(restricted variant) from std.variant, is there? implementation issue?
|
Copyright © 1999-2021 by the D Language Foundation