In C++ you can create templated classes that use a particular operator on the
templated objects and the class from which these objects are instantiated
must overload that particular operator for its objects to work with the
templated class. For example, the `insertion` method for a BST implementation
might rely on the `<` operator and thus any object to be stored in a BST
must implement that operator.

If possible, how can I do the same with parameterized roles in Raku?

---

In order to provide some context, take for example the following parameterized role defined as its own module:

```
role BST[::T] {
    my role BinaryNode[::T] {
        has T $.item           is rw;
        has BinaryNode $.left  is rw;
        has BinaryNode $.right is rw;
    }

    has BinaryNode $!root;

    method insert( BST:D: T $x --> Nil ) {
        self!rec-insert($x, $!root)
    }

    method !rec-insert( T $x, BinaryNode $node is rw --> Nil ) {
        if !$node.defined     { $node = BinaryNode[$(T)].new(item => $x) }
        elsif $x < $node.item { self!rec-insert($x, $node.left) }
        elsif $node.item < $x { self!rec-insert($x, $node.right) }
        else                  { } # Duplicate; do nothing
    }
}

```

Then, it could be used to store integers:

```
use BST;
my $bst = BST[Int].new;

$bst.insert($_) for 6, 3, 2, 1, 4;

```

However, trying some user-defined type I haven't been able to make it work.
Suppose we've defined a `Point2D` class and the less-than relationship between
two `Point2D` objects is defined by their distance to the center
(e.g., `Point2D.new(:3x, :4x)` is less than `Point2D.new(:6x, :8y)`):

```
use BST;

class Point2D {
    has $.x;
    has $.y;

    multi method distance {
        (($!x - 0) ** 2 ($!y - 0) ** 2).sqrt
    }
}

multi infix:«<»( Point2D:D $lhs, Point2D:D $rhs --> Bool ) {
    return $lhs.distance < $rhs.distance
}

my $bst = BST[Point2D].new;

$bst.insert(Point2D.new(:1x, :4y));
$bst.insert(Point2D.new(:3x, :4y));

=begin comment
Cannot resolve caller Real(Point:D: ); none of these signatures match:
    (Mu:U \v: *%_)
  in method rec-insert ...
  in method insert ...
=end comment

```

My not-so-educated guess is that the operator `<` for `Point2D` is lexical, and thus `BST` doesn't pick it up. [If overloading an operator in a module, it's recommended to export it so that it will be available to users who `use` or `import` the module](https://stackoverflow.com/a/55814306). However, I don't think that makes much sense with `BST` since objects of a particular class will define their relational relationship differently. Furthermore, I'm not even sure if that would work with type captures.