ReturnTypeテンプレートのファンクタ対応

一瞬恥ずかしい日記があった気がしますが気のせいです。
std.traitsのReturnTypeテンプレートは、opCallを実装したファンクタには対応していません。適当に対応させてみます。

template MyReturnType(alias dg){ 
    static if (is(typeof(dg) R == return)){
        alias R MyReturnType;
    } else static if (is(typeof(dg.opCall) T)){
        static if (is(T R == return)){
            alias R MyReturnType;
        }
    } else {
        static assert(0);
    }
}

template MyReturnType(dg){
    static if (is(dg R == return)){
        alias R MyReturnType;
    } else static if (is(dg.opCall T)){
        static if (is(T R == return)){
            alias R MyReturnType;
        }
    } else {
        static assert(0);
    }
}

ここで「あれ?std.traitsみたく…」

template MyReturnType(alias dg){ 
    alias MyReturnType!(typeof(dg)) MyReturnType;
}

「…ってすればいいんじゃないの?」と思った人。あなたは賢い、ですが正しくはありません。現実は厳しいのです!
どういうことかというと、ファンクタを渡した途端に「再帰的なaliasです!」と叱られてしまうのでした。
まあそんなはずはないわけですが、コンパイラがそう言ったんだからきっとそうなんだろうよ!ぺっ!
追記:Dスレ10で、同じ働きのもっとシンプルな物を発見したのだった。
更に追記:折角なので全部書いておいた

template MyReturnType(alias dg){
    static if (is(typeof(dg.opCall) T)){
        alias ReturnType!(T) MyReturnType;
    } else {
        alias ReturnType!(dg) MyReturnType;
    }
}

template MyReturnType(dg){
    static if (is(dg.opCall T)){
        alias ReturnType!(T) MyReturnType;
    } else {
        alias ReturnType!(dg) MyReturnType;
    }
}

template MyParameterTypeTuple(alias dg){
    static if (is(typeof(dg.opCall) T)){
        alias ParameterTypeTuple!(T) MyParameterTypeTuple;
    } else {
        alias ParameterTypeTuple!(dg) MyParameterTypeTuple;
    }
}

template MyParameterTypeTuple(dg){
    static if (is(dg.opCall T)){
        alias ParameterTypeTuple!(T) MyParameterTypeTuple;
    } else {
        alias ParameterTypeTuple!(dg) MyParameterTypeTuple;
    }
}