On 2/6/20 7:16 AM, mark wrote:
I am starting on porting Python's difflib's sequence matcher to D.

I want to have a class that will accept two ranges whose elements are of the same type and whose elements can be compared for equality.

How do I make a class declaration that specifies a (forward) range type and an equality-supporting element type?

Here's what doesn't work:

class Diff(T, E) {
     T a; // T should be a forward range of E elements
     T b; // E elements must support == and !=
         // This is a hash key=E element, value=slice of size_t
     size_t[][E] b2j;

     this(T a, T b) {
         this.a = a;
         this.b = b;
         chainB();
     }

     void chainB() {
         foreach (i, element; b)
             b2j[element] ~= i;
         // TODO
     }
}

unittest {
     import std.stdio: writeln;

     writeln("unittest for the diffrange library.");
     auto a = ["Tulips are yellow,", "Violets are blue,",
                   "Agar is sweet,", "As are you."];
     auto b = ["Roses are red,", "Violets are blue,",
                   "Sugar is sweet,", "And so are you."];
     auto diff = Diff(a, b);
}


1. If one template parameter depends 100% on the other, it doesn't need to be a parameter. i.e. I would do:

class Diff(T) {
   alias E = ElementType!T;
   ...
}

2. Class constructors do not support IFTI. You have to explicitly instantiate. To use IFTI, you need to create a factory function. i.e. to make the code above work, your ctor call should be Diff!(typeof(a)) (assuming you take the advice in 1).

But you can instead write a function to use IFTI:

auto makeDiff(T)(T r1, T r2) { return Diff!T(r1, r2); }

...

auto diff = makeDiff(a, b);

3. You should declare constraints signifying what types are valid. i.e.:

class Diff(T) if (
   isForwardRange!T // it's a forward range
   && is(typeof(T.init.front == T.init.front)) // elements are comparable
)

Might be good to put this constraint on the factory function too.

Note: is(typeof(...)) basically checks if the thing inside the typeof compiles.

-Steve

Reply via email to