user
Parametric polymorphism is a way to define types or functions that are generic over other types. The genericity can be expressed by using *type variables* for the parameter type, and by a mechanism to explicitly or implicitly replace the type variables with concrete types when necessary.

Task

Write a small example for a type declaration that is parametric over another type, together with a short bit of code (and its type signature) that uses it.

A good example is a container type, let's say a binary tree, together with some function that traverses the tree, say, a *map*-function that operates on every element of the tree.

This language feature only applies to statically-typed languages.
assistant
(formerly Perl 6)

**Works with**: Rakudo version 2020.08.1

```
role BinaryTree[::T] {
    has T $.value;
    has BinaryTree[T] $.left;
    has BinaryTree[T] $.right;

    method replace-all(T $value) {
        $!value = $value;
        $!left.replace-all($value) if $!left.defined;
        $!right.replace-all($value) if $!right.defined;
    }
}

class IntTree does BinaryTree[Int] { }

my IntTree $it .= new(value => 1,
                      left  => IntTree.new(value => 2),
                      right => IntTree.new(value => 3));

$it.replace-all(42);
say $it;

```

Output:

```
IntTree.new(value => 42, left => IntTree.new(value => 42, left => BinaryTree[T], right => BinaryTree[T]), right => IntTree.new(value => 42, left => BinaryTree[T], right => BinaryTree[T]))
```