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.


Page was generated with on Fri Nov 12 11:55:10 2010