Parametric Polymorphism
type variables


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.




interface TreeAny guards TreeStamp {}
def Tree {
    to get(Value) {
        def Tree1 {
            to coerce(specimen, ejector) {
                def tree := TreeAny.coerce(specimen, ejector)
                if (tree.valueType() != Value) {
                    throw.eject(ejector, "Tree value type mismatch")
                }
                return tree
            }
        }
        return Tree1
    }
}
 
def makeTree(T, var value :T, left :nullOk[Tree[T]], right :nullOk[Tree[T]]) {
    def tree implements TreeStamp {
        to valueType() { return T }
        to map(f) {
            value := f(value)  # the declaration of value causes this to be checked
            if (left != null) {
                left.map(f)
            }
            if (right != null) {
                right.map(f)
            }
        }
    }
    return tree
}