Algebra With Types

David Sanders via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Fri Apr 21 11:54:38 PDT 2017


On Friday, 21 April 2017 at 17:33:22 UTC, Meta wrote:
> On Friday, 21 April 2017 at 16:31:37 UTC, H. S. Teoh wrote:
>> On Fri, Apr 21, 2017 at 04:16:30PM +0000, David Sanders via 
>> Digitalmars-d-learn wrote:
>>> 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?
>> [...]
>>
>> static if (is(T : Algebraic!(U...), U))
>> {
>> 	// U now refers to the argument to Algbraic.
>> }
>>
>>
>> --T
>
> There's also a private `isAlgebraic` template[1]. Is there any 
> reason why we couldn't just make this public?
>
> 1. 
> https://github.com/dlang/phobos/blob/master/std/variant.d#L2236

Thank-you for your input. With your help, I was able to figure 
out number whether a type is an instantiation of 
std.variant.Algebraic.

Now, I need help on concatenating Template Sequence Parameters. 
See the block comments below.

Thanks,
Dave

import std.stdio;
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 (is(T _ == VariantN!V, V...)) {
		static if(is(U _ == VariantN!W, W...)) {
			alias type = Algebraic!/* Concatenate V[1..$] with U[1..$] */
		} else {
			alias type = Algebraic!/* Concatenate V[1..$] with U */
		}
	} else static if(is(U _ == VariantN!V, V...)) {
		alias type = Algebraic!/* Concatenate T with V[1..$] */
	} 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));
}


More information about the Digitalmars-d-learn mailing list