3

Assuming I have the following classes in Haxe:

class Pair<U, V> {
    public var first:U = null;
    public var second:V = null;
    public function new(u:U, v:V) {
        this.first = u;
        this.second = v;
    }
}
class HashablePair<U:{ function hashCode():Int; }, V:{ function hashCode():Int; }> {
    public var first:U = null;
    public var second:V = null;
    public function new(u:U, v:V) {
        this.first = u;
        this.second = v;
    }
    public function hashCode():Int { // just a sample way ...
        var h1:Int = (first == null) ? 0 : first.hashCode();
        var h2:Int = (second == null) ? 0 : second.hashCode();
        return 3 * h1 + 5 * h2;
    }
}

I wondered if it is possible to write a macro that adds the hashCode function to the pair class, if and only if both generics U and V implement the hashCode-function ... and thus make it possible to combine the two classes into a single one via meta-programming.

quant
  • 2,184
  • 2
  • 19
  • 29

1 Answers1

3

You can achieve the desired behavior by simply switching to an abstract:

typedef Hashable = { function hashCode():Int; };

abstract HashablePair<U:Hashable,V:Hashable>(Pair<U,V>)from Pair<U,V> {
    public function new(u:U, v:V)
        this = new Pair(u, v);

    public function hashCode():Int { // just a sample way ...
        var h1:Int = (this.first == null) ? 0 : this.first.hashCode();
        var h2:Int = (this.second == null) ? 0 : this.second.hashCode();
        return 3 * h1 + 5 * h2;
    }
}

The from Pair<U,V> makes Pair<U,V> casts to HashablePair<U,V> allowed, as long as the necessary constrains on U and V are respected.

For a complete exemple, check out Try Haxe #d76E1.

Jonas Malaco
  • 1,557
  • 9
  • 18
  • Interesting ... Not a macro as I thought I would need it - but definitely a go able way - Tks – quant Nov 24 '17 at 10:59