type_theory.d:
```
module type_theory;
import std.conv;
import prod;

class Type
{
public:
   Prod opBinary(string op="*")(Type r)
   {
      alias l = this;
      return new Prod(l, r);
   }

   Type opBinary(string op="^")(int k)
   in {
      assert (k > 0);
   }
   do {
      if (k == 1)
         return this;

      auto P = this;

      while (k > 0)
      {
         k --;
         P = this * P;
      }

      return P;
   }

   override string toString() {
      auto str = to!string(cast(void*) this);
      if (isAtomic)
         return str;
      return "(" ~ str ~ ")";
   }

   @property string typename() {
      return typeof(this).stringof;
   }

   string typingString() {
      return *this ~ ":" ~ typename;
   }

   string opUnary(string op="*")() {
      return toString();
   }

   bool isAtomic() { return false; }
}

```

prod.d:
```
module prod;
import type_theory;

class Prod : Type
{
public:
   this(Type l, Type r)
   {
      this.l = l;
      this.r = r;
   }

   @property Type left() { return l; }
   @property Type right() { return r; }

   override string toString() {
      return "(" ~ *l ~ r"\times " ~ *r ~ ")";
   }

protected:
   Type r,l;
}

unittest {
   import std.stdio;
   auto A = new Type();
   auto P = new Prod(A,A);
   writeln("P = ", P);
   readln();
}
```

var.d:
```
module var;

import type_theory;

class Var : Type
{
public:
   alias assign this;

   this(string syms)
   {
      this.syms = syms;
   }

   Var opOpAssign(string op="~")(Type assign)
   {
      this.assign = assign;
      return this;
   }

   override string toString() { return syms; }

   @property override bool isAtomic() { return true; }

protected:
   Type assign;
   string syms;
}


unittest {
   import std.stdio;

   Var A = new Var("A");
   A ~= new Type();
   writeln(A);
   auto B = A*A^2;
   writeln(A);

   writeln("B=", B);
   readln();
}
```

Result should be "A\times (A\times A)" however it's always coming out (in the var.d unittest):

```
B=((A\times A)\times ((A\times A)\times (A\times A)))
```

In other words when it is supposed to print `A` for each of the components, it instead prints "A\times A".

Please give me a D recipe for accomplishing this relatively simple thing.

Thanks!

Reply via email to