Parametric polymorphism: Difference between revisions

Added Wren
(Tidied up the second Go example and made it clear this depends on generics being added to the language.)
(Added Wren)
Line 1,446:
succeed().
</lang>
 
=={{header|Wren}}==
{{trans|Kotlin}}
Wren is dynamically type and so doesn't have parametric polymorphism (PP) as such; in a sense every method or function is polymorphic over its parameters.
 
However, that doesn't mean that type safety is unimportant and, in the case of a Binary Tree, we'd generally want all its nodes to contain values of the same type.
 
Fortunately, we can simulate PP by passing an extra parameter to a collection class's contructor to specify the type of values to be used for that particular instantiation. We can then use this to guard against the wrong type of values being passed to the class's other methods.
<lang ecmascript>class BinaryTree {
construct new(T, value) {
if (!(T is Class)) Fiber.abort ("T must be a class.")
if (value.type != T) Fiber.abort("Value must be of type T.")
_kind = T
_value = value
_left = null
_right = null
}
 
// constructor overload to enable kind to be inferred from type of value
static new (value) { new(value.type, value) }
 
kind { _kind }
value { _value}
value=(v) {
if (v.type != _kind) Fiber.abort("Value must be of type %(_kind)")
_value = v
}
 
left { _left }
right { _right }
left=(b) {
if (b.type != BinaryTree || b.kind != _kind) {
Fiber.abort("Argument must be a BinaryTree of type %(_kind)")
}
_left = b
}
right=(b) {
if (b.type != BinaryTree || b.kind != _kind) {
Fiber.abort("Argument must be a BinaryTree of type %(_kind)")
}
_right = b
}
 
map(f) {
var tree = BinaryTree.new(f.call(_value))
if (_left) tree.left = left.map(f)
if (_right) tree.right = right.map(f)
return tree
}
 
showTopThree() { "(%(left.value), %(value), %(right.value))" }
}
 
var b = BinaryTree.new(6)
b.left = BinaryTree.new(5)
b.right = BinaryTree.new(7)
System.print(b.showTopThree())
 
var b2 = b.map{ |i| i * 10 }
System.print(b2.showTopThree())
b2.value = "six" // generates an error because "six" is not a Num</lang>
 
{{out}}
<pre>
(5, 6, 7)
(50, 60, 70)
Value must be of type Num
[./parametric_polymorphism line 17] in value=(_)
[./parametric_polymorphism line 53] in (script)
 
</pre>
 
 
 
9,485

edits