Parametric polymorphism: Difference between revisions

Content added Content deleted
(Added Scala)
m (Fixed lang tags.)
Line 7: Line 7:


=={{header|Ada}}==
=={{header|Ada}}==
<lang ada>
<lang ada>generic
type Element_Type is private;
generic
package Container is
type Element_Type is private;
type Tree is tagged private;
package Container is
procedure Replace_All(The_Tree : in out Tree; New_Value : Element_Type);
type Tree is tagged private;
private
procedure Replace_All(The_Tree : in out Tree; New_Value : Element_Type);
type Node;
private
type Node;
type Node_Access is access Node;
type Node_Access is access Node;
type Tree tagged record
Value : Element_type;
type Tree tagged record
Value : Element_type;
Left : Node_Access := null;
Left : Node_Access := null;
Right : Node_Access := null;
end record;
Right : Node_Access := null;
end Container;</lang>
end record;
end Container;
<lang ada>package body Container is
procedure Replace_All(The_Tree : in out Tree; New_Value : Element_Type) is
</lang>
begin
<lang ada>
The_Tree.Value := New_Value;
package body Container is
If The_Tree.Left /= null then
procedure Replace_All(The_Tree : in out Tree; New_Value : Element_Type) is
The_Tree.Left.all.Replace_All(New_Value);
begin
The_Tree.Value := New_Value;
end if;
If The_Tree.Left /= null then
if The_tree.Right /= null then
The_Tree.Left.all.Replace_All(New_Value);
The_Tree.Right.all.Replace_All(New_Value);
end if;
end if;
end Replace_All;
if The_tree.Right /= null then
end Container;</lang>
The_Tree.Right.all.Replace_All(New_Value);
end if;
end Replace_All;
end Container;
</lang>


=={{header|C++}}==
=={{header|C++}}==


<lang cpp> template<class T>
<lang cpp>template<class T>
class tree
class tree
{
{
T value;
T value;
tree *left;
tree *left;
tree *right;
tree *right;
public:
public:
void replace_all (T new_value);
void replace_all (T new_value);
};</lang>
};</lang>


For simplicity, we replace all values in the tree with a new value:
For simplicity, we replace all values in the tree with a new value:


<lang cpp> template<class T>
<lang cpp>template<class T>
void tree<T>::replace_all (T new_value)
void tree<T>::replace_all (T new_value)
{
{
value = new_value;
value = new_value;
left->replace_all (new_value);
left->replace_all (new_value);
right->replace_all (new_value);
right->replace_all (new_value);
}</lang>
}</lang>


=={{header|Clean}}==
=={{header|Clean}}==
Line 118: Line 114:
}</lang>
}</lang>
This is a using example.
This is a using example.
<lang d>
<lang d>module polytest ;
module polytest ;
import std.stdio ;
import std.stdio ;
import parapoly ;
import parapoly ;
Line 219: Line 214:
=={{header|Java}}==
=={{header|Java}}==
Following the C++ example:
Following the C++ example:
<lang java> public class Tree<T>{
<lang java>public class Tree<T>{
private T value;
private T value;
private Tree<T> left;
private Tree<T> left;
private Tree<T> right;
private Tree<T> right;

public void replaceAll(T value){
public void replaceAll(T value){
this.value = value;
this.value = value;
if(left != null)
if(left != null)
left.replaceAll(value);
left.replaceAll(value);
if(right != null)
if(right != null)
right.replaceAll(value);
right.replaceAll(value);
}
}
}</lang>
}</lang>


=={{header|OCaml}}==
=={{header|OCaml}}==


<lang ocaml> type 'a tree = Empty | Node of 'a * 'a tree * 'a tree
<lang ocaml>type 'a tree = Empty | Node of 'a * 'a tree * 'a tree


(** val map_tree : ('a -> 'b) -> 'a tree -> 'b tree *)
(** val map_tree : ('a -> 'b) -> 'a tree -> 'b tree *)
let rec map_tree f = function
let rec map_tree f = function
| Empty -> Empty
| Empty -> Empty
| Node (x,l,r) -> Node (f x, map_tree f l, map_tree f r)</lang>
| Node (x,l,r) -> Node (f x, map_tree f l, map_tree f r)</lang>


=={{header|Scala}}==
=={{header|Scala}}==
Line 322: Line 317:
=={{header|Standard ML}}==
=={{header|Standard ML}}==


<lang sml> datatype 'a tree = Empty | Node of 'a * 'a tree * 'a tree
<lang sml>datatype 'a tree = Empty | Node of 'a * 'a tree * 'a tree


(** val map_tree = fn : ('a -> 'b) -> 'a tree -> 'b tree *)
(** val map_tree = fn : ('a -> 'b) -> 'a tree -> 'b tree *)
fun map_tree f Empty = Empty
fun map_tree f Empty = Empty
| map_tree f (Node (x,l,r)) = Node (f x, map_tree f l, map_tree f r)</lang>
| map_tree f (Node (x,l,r)) = Node (f x, map_tree f l, map_tree f r)</lang>


=={{header|Ursala}}==
=={{header|Ursala}}==
Line 332: Line 327:
routinely. A parameterized binary tree type can be defined using a syntax for anonymous
routinely. A parameterized binary tree type can be defined using a syntax for anonymous
recursion in type expressions as in this example,
recursion in type expressions as in this example,
<lang Ursala>binary_tree_of "node-type" = "node-type"%hhhhWZAZ</lang>
<lang Ursala>
binary_tree_of "node-type" = "node-type"%hhhhWZAZ
</lang>
or by way of a recurrence solved using a fixed point combinator imported from a library
or by way of a recurrence solved using a fixed point combinator imported from a library
as shown below.
as shown below.
<lang Ursala>
<lang Ursala>#import tag
#import tag


#fix general_type_fixer 1
#fix general_type_fixer 1


binary_tree_of "node-type" = ("node-type",(binary_tree_of "node-type")%Z)%drWZwlwAZ
binary_tree_of "node-type" = ("node-type",(binary_tree_of "node-type")%Z)%drWZwlwAZ</lang>
</lang>
(The %Z type operator constructs a "maybe" type, i.e., the free union of its operand type
(The %Z type operator constructs a "maybe" type, i.e., the free union of its operand type
with the null value. Others shown above are standard stack manipulation primitives, e.g. d (dup) and w (swap), used to build the type expression tree.) At the other extreme, one may construct an equivalent parameterized type in
with the null value. Others shown above are standard stack manipulation primitives, e.g. d (dup) and w (swap), used to build the type expression tree.) At the other extreme, one may construct an equivalent parameterized type in
point-free form.
point-free form.
<lang Ursala>
<lang Ursala>binary_tree_of = %-hhhhWZAZ</lang>
binary_tree_of = %-hhhhWZAZ
</lang>
A mapping combinator over this type can be defined with pattern matching like this
A mapping combinator over this type can be defined with pattern matching like this
<lang Ursala>binary_tree_map "f" = ~&a^& ^A/"f"@an ~&amPfamPWB</lang>
<lang Ursala>
binary_tree_map "f" = ~&a^& ^A/"f"@an ~&amPfamPWB
</lang>
or in point free form like this.
or in point free form like this.
<lang Ursala>
<lang Ursala>binary_tree_map = ~&a^&+ ^A\~&amPfamPWB+ @an</lang>
binary_tree_map = ~&a^&+ ^A\~&amPfamPWB+ @an
</lang>
Here is a test program
Here is a test program
defining a type of binary trees of strings, and a function that concatenates each node
defining a type of binary trees of strings, and a function that concatenates each node
with itself.
with itself.
<lang Ursala>
<lang Ursala>string_tree = binary_tree_of %s
string_tree = binary_tree_of %s


x = 'foo': ('bar': (),'baz': ())
x = 'foo': ('bar': (),'baz': ())
Line 368: Line 352:
#cast string_tree
#cast string_tree


example = (binary_tree_map "s". "s"--"s") x
example = (binary_tree_map "s". "s"--"s") x</lang>
</lang>
Type signatures are not associated with function declarations, but
Type signatures are not associated with function declarations, but
have uses in the other contexts such as assertions and compiler directives
have uses in the other contexts such as assertions and compiler directives