よくわからない template

以前ちょっと触ったことはあったけど,本当に触っただけだったD言語でいろいろやってみようと思った.
まぁとりあえず型とか template とかですよね.
static if とか is とか alias が便利すぎてすごい.
型レベルプログラミングの会の k.inaba さんの資料を参考にしながら,型リストに対するなんちゃらとかを書いてみた.
http://gist.github.com/191428


しかしよくわからない問題にぶつかったのでメモ.

class Nil {}
class Cons(X, XS) {}

template foldr(alias F, A, T) {
  static if (is(T == Nil)) {
    alias A foldr;
  } else static if (is(T _ == Cons!(X, XS), X, XS)) {
    alias F!(X, foldr!(F, A, XS)) foldr;
  }
}

template foldl(alias F, A, T) {
  static if (is(T == Nil)) {
    alias A foldl;
  } else static if (is(T _ == Cons!(X, XS), X, XS)) {
    alias foldl!(F, F!(A, X), XS) foldl;
  }
}

class Zero {}
class Succ(Z) {}

template add(T, U) {
  static if (is(T == Zero)) {
    alias U add;
  } else static if (is(T _ == Succ!(V), V)) {
    alias Succ!(add!(V, U)) add;
  }
}

void main()
{
  alias Succ!(Zero) one;
  alias Succ!(Succ!(Zero)) two;

  static assert(is(foldl!(add, Zero, Cons!(two, Nil)) == two)); /* この static if は通る */

  alias add!(two, Zero) _;  /* この行をコメントアウトすると, */
  static assert(is(foldr!(add, Zero, Cons!(two, Nil)) == two)); /* この static if に失敗する */
}

template の instantiate のタイミングの問題なのかなぁ.