www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Some pattern matching for the type level functions

In this code example, given an instantiated struct type 
Foo!(T1,T2) I want to define a Bar struct with the types 
Bar!(T1,T2,T1). The Mapper template acts as a rank-2-safe type 
level function (it's safe thanks to the use to IsFoo):


import std.traits: Unqual;

struct Foo(TT1, TT2) {
     alias T1 = TT1;
     alias T2 = TT2;
}

struct Bar(T1, T2, T3) {}

template IsFoo(T) {
     static if (is(Unqual!T Unused : Foo!Types, Types...))
         enum IsFoo = true;
     else
         enum IsFoo = false;
}

template Mapper(F) if (IsFoo!F) {
     alias Mapper = Bar!(F.T1, F.T2, F.T1);
}

void main() {
     Mapper!(Foo!(int, float)) bar;
}

------------------

D template functions allow a limited but useful form of pattern 
matching on types:

struct Foo(TT1, TT2) {
     alias T1 = TT1;
     alias T2 = TT2;
}
void bar(T1, T2)(Foo!(T1, T2) f) {}
void main() {
     Foo!(int, float) f;
     bar(f);
}

------------------

So is it a good idea to add some safe pattern matching on types 
to the recently added short syntax for alias/enum templates, like 
this?


struct Foo(TT1, TT2) {
     alias T1 = TT1;
     alias T2 = TT2;
}

struct Bar(T1, T2, T3) {}

alias Mapper(Foo!(T1, T2)) = Bar!(T1, T2, T1);

void main() {
     Mapper!(Foo!(int, float)) bar;
}


(A similar pattern matching on types can be used in Haskell for 
type level functions.)

------------------

Note that currently you can write:

alias MapperShort(F) = Bar!(F.T1, F.T2, F.T1);

But you can't write (but perhaps Kenji san asked for something 
like this):

alias MapperShort(F) if (IsFoo!F) = Bar!(F.T1, F.T2, F.T1);

So MapperShort is not safe if you want to use the short syntax.

Bye,
bearophile
Jan 28 2014