dranges.patternmatch
This module leverages the pattern-matching nature of templates to provide a basic pattern-matching
function. The main function here is match , the engine behind ($ dranges.functional.eitherFun).
See below for more doc.
My goal is to link into a coherent whole all the pattern-matching modules in dranges: this one, dranges.typepattern ,
dranges.tuplepattern , drange.ctre and maybe use them to map and transform tuple-trees. A far-away
but inspirational goal is to get an AST from D code, transform it and recombine it into another AST, reducing it down
to a string reprensenting D code. That is, a sort of macro system for D. It's but a dream, but it's a also a fun journey.
License:
Boost License 1.0.
Authors:
Philippe Sigaud
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
- template
match
(alias fun,Rest...)
match
is a pattern taking any number of function, templated or not, as input. When you then pass it a value,
match
will test the value with the passed-in functions in the order they were passed-in,
see if they
match
or not and return the result of the first function that matches.
If no function matches,
match
will throw a NoMatchException .
The provided functions are template parameters and so must be known at compile-time.
The interesting part is that, being a template and acting on templated functions,
match
can potentially accept any type
and return any other type. It uses the inherent pattern-matching done by templates to find a
match
. All the type-patterns and template constraints
you're used to can be used there.
For example:
T one(T)(T t) { return t;} // matches any lone type
T[] twoEqual(T)(T t1, T t2) { return [t1,t2];} // matches if the input is twice the same type
Tuple!(T,U) twoDiff(T,U)(T t, U u) { return tuple(t,u);} // Matches any two types
string three(T)(T t1, T t2, T t3) { return T.stringof ~ " thrice";} // Thrice the same type
string threeDiff(T,U,V)(T t, U u, V v) // Any three types.
{ return T.stringof ~ " " ~ U.stringof ~ " " ~ V.stringof;}
alias match!(one,
twoEqual,
twoDiff,
three,
threeDiff,
any) m;
assert(m(1) == 1); // one type
assert(m('a','b') = ['a','b']); // twice the same type. twoEqual is tested before two
assert(m('a', 2.34) == tuple('a',2.34)); // two different types. twoEqual is not activated, but twoDiff is.
m("aha", 1, 3.1415, 'a'); // no match!
See Also:
.
- template
amatch
(Funs...)
- Another matching function, this one working on algebraic types from
std.typecons .
The passed-in functions must be standard, non-templated functions which all return the same type
and must match the types allowed by the algebraic.
That is, if you have an Algebraic!(int, double, string) ,
one function must accept an int, another must accept a double and a third must accept
a string. Or rather, given this triplet of function
amatch
!(funs) will not accept
an Algebraic which does not have int , string and double as allowed types.
Note that the order is not important, the types are all sorted internally.
Example:
Algebraic!(int, string, double) alg;
string foo(int i) { return to!string(i+1);}
string bar(double d) { return to!string(d*d);}
string baz(string s) { return "";}
alias amatch!(foo,bar,baz) matcher;
alg = 3;
assert(matcher(alg) == "4"); // int function activated.
alg = "abc";
assert(matcher(alg) == ""); // string function activated.
alg = 3.0;
assert(matcher(alg) == "9.0"); // int function activated.
|