digitalmars.D.learn - Structural exhaustive matching
- Jadbox (3/3) Apr 21 2015 What's the best equivalent to Rust's structural enum/pattern
- bearophile (10/11) Apr 21 2015 Sometimes there's no best way, there are several alternative ways
- weaselcat (3/6) Apr 21 2015 D's ADTs are in std.variant, the equivalent of matching is the
- Justin Whear (20/23) Apr 21 2015 std.variant.Algebraic implements ADTs:
- Jacob Carlborg (6/9) Apr 21 2015 There's something call "castSwitch" [1], perhaps not what you're looking...
- Martin Nowak (23/26) Apr 21 2015 If it needs to be really fast, use final switch on the tag of a
- weaselcat (3/29) Apr 21 2015 there's no reason this should be faster than Algebraic(restricted
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.
Apr 21 2015
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
Apr 21 2015
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
Apr 21 2015
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.
Apr 21 2015
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. -- /Jacob Carlborg
Apr 21 2015
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; } }
Apr 21 2015
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:there's no reason this should be faster than Algebraic(restricted variant) from std.variant, is there? implementation issue?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; } }
Apr 21 2015