The OpenD Programming Language

tryMatch

Behaves as match but doesn't enforce at compile time that all types can be handled by the visiting functions.

import mir.algebraic;
alias tryMatch(visitors...) = visitImpl!(naryFun!visitors, Exhaustive.exception, true)

Throws

Exception if naryFun!visitors can't be called with provided arguments

Fuses algebraic types on return.

Examples

1 import std.exception: assertThrown;
2 static struct Asteroid { uint size; }
3 static struct Spaceship { uint size; }
4 alias SpaceObject = Variant!(Asteroid, Spaceship);
5 
6 alias collideWith = tryMatch!(
7     (Asteroid x, Asteroid y) => "a/a",
8     // No visitor for A/S pair
9     // (Asteroid x, Spaceship y) => "a/s",
10     (Spaceship x, Asteroid y) => "s/a",
11     (Spaceship x, Spaceship y) => "s/s",
12 );
13 
14 import mir.utility: min;
15 // Direct access of a member in case of all algebraic types has this member
16 alias oops = (a, b) => (a.size + b.size) > 3 && min(a.size, b.size) > 1;
17 
18 alias collide = (x, y) => oops(x, y) ? "big-boom" : collideWith(x, y);
19 
20 auto ea = Asteroid(1);
21 auto es = Spaceship(2);
22 auto oa = SpaceObject(ea);
23 auto os = SpaceObject(es);
24 
25 // Asteroid-Asteroid
26 assert(collide(ea, ea) == "a/a");
27 assert(collide(ea, oa) == "a/a");
28 assert(collide(oa, ea) == "a/a");
29 assert(collide(oa, oa) == "a/a");
30 
31 // Asteroid-Spaceship
32 assertThrown!Exception(collide(ea, es));
33 assertThrown!Exception(collide(ea, os));
34 assertThrown!Exception(collide(oa, es));
35 assertThrown!Exception(collide(oa, os));
36 
37 // can deduce the type based on other return values
38 static assert(is(typeof(collide(ea, os)) == string));
39 static assert(is(typeof(collide(oa, es)) == string));
40 static assert(is(typeof(collide(oa, os)) == string));
41 
42 // Also allows newer compilers to detect combinations which always throw an exception
43 static if (is(typeof(collideWith(ea, es)) == noreturn))
44 {
45     static assert(is(typeof(collide(ea, es)) == string));
46 }
47 else
48 {
49     // not enough information to deduce the type from (ea, es) pair
50     static assert(is(typeof(collide(ea, es)) == void));
51 }
52 
53 // Spaceship-Asteroid
54 assert(collide(es, ea) == "s/a");
55 assert(collide(es, oa) == "s/a");
56 assert(collide(os, ea) == "s/a");
57 assert(collide(os, oa) == "s/a");
58 
59 // Spaceship-Spaceship
60 assert(collide(es, es) == "big-boom");
61 assert(collide(es, os) == "big-boom");
62 assert(collide(os, es) == "big-boom");
63 assert(collide(os, os) == "big-boom");

Meta