I'm trying to do algebra with types ala http://chris-taylor.github.io/blog/2013/02/10/the-algebra-of-algebraic-data-types/

Below you will find my attempts at "adding" types in D. I've outlined the parts I'm having trouble with using block comments.

1) How do I figure out whether a type is an instantiation of std.variant.Algebraic?
2) If the type is Algebraic, how do I capture its AllowedTypes?

Thanks,
Dave

import std.variant;

alias Zero = void;

struct One{};

struct Sum(T, U) {
    static if (is(T == Zero)) {
        static if (is(U == Zero)) {
            alias type = Zero;
        }
        else {
            alias type = U;
        }
    } else static if (is(U == Zero)) {
        alias type = T;
    } else static if (/* T is Algebraic */) {
        static if (/* U is Algebraic */) {
alias type = Algebraic!/* Concatenate T.AllowedTypes with U.AllowedTypes */
        } else {
alias type = Algebraic!/* Concatenate T.AllowedTypes with U */
        }
    } else static if (/* U is Algebraic */) {
alias type = Alegebraic!/* Concatenate T with U.AllowedTypes */
    } else {
        alias type = Algebraic!(T, U);
    }   
}

void main() {
    static assert (is(Zero == Sum!(Zero, Zero).type));
    static assert (is(One == Sum!(Zero, One).type));
    static assert (is(One == Sum!(One, Zero).type));
static assert (is(Algebraic!(One, One) == Sum!(One, One).type)); static assert (is(Algebraic!(One, One, One) == Sum!(Sum!(One, One).type, One).type));
}

Reply via email to