pattern matching in D

No pattern matching as known from Haskell is built in into language, but D has very generic compile time and reflection capabilities that will allow you to match type and their structure in library. For matching runtime values you can use only ordinary if / switch ... constructs; lazy evaluation of function arguments might also help with implementation of some matching-at-runtime techniques.

Template Constraints will allow you to create function (template) overloads based on any expression evaluated at compile time (D allows you to execute almost all normal code during compilation). You can also use static if for similar effect. This will practically allow you to match type structure. This is also commonly used technique in D.

You might find code of std.algorithm interesting, look for isInputRange and similar functions - they perform matching on type structure - they restrict type of argument to be of certain typeclass

Some directions for compile time reflection:

  • Is Expression
  • Traits
  • std.traits

There is no dedicated pattern-matching feature as powerful as in Haskell or Scala.

As you have already figured out, overloading and calling (templated) functions or delegates is a restricted form of pattern matching. You can match on the argument types only.

You can pattern match on compile time template arguments. It is not possible to extract an object's contents there either. But you can extract a type's contents.

Eg :

import std.stdio, std.conv;
template match(T...){
    enum match = "default case";
}
template match(string a : "x", int b : 1, int  c){
    enum match = "matched 1, b="~to!string(b);
}
template match(int a, string b, int c : 100){
    enum match = "matched 2, b="~b;
}
template match(T : T[]*[]){
    enum match = "matched 3, an array of pointers to an array of "~T.stringof;
}


void main(){
    int a=100;
    writeln(match!("x",1,5));        // "matched 1, b=1"                                                                                                     
    writeln(match!(12,"str"));       // "default case"                                                                                                       
    writeln(match!(12,"str",100));   // "matched 2, b=str"                                                                                                   
    writeln(match!(int*[]*[]));      // "matched 3, an array of pointers to an array of int*"                                                                
    //writeln(match!(12,"str",a));   // would be error, because 'a'                                                                                            
                                     // is not evaluable during compile time                                                                                 
}

If you are interested, you may want to have a look at http://d-programming-language.org/template.html .

'is' - Expressions are another way to pattern match on types, see

http://d-programming-language.org/expression.html (search for "IsExpression").