How do you implement complementary "A*(A*A) = A^3" operator overloads (I'm getting strange results)

Daniel Daniel
Mon Aug 19 09:42:44 UTC 2024


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!


More information about the Digitalmars-d-learn mailing list