tasks a-s
This commit is contained in:
parent
47bf37c096
commit
b83f433714
12433 changed files with 156208 additions and 123 deletions
5
Task/Parametric-polymorphism/0DESCRIPTION
Normal file
5
Task/Parametric-polymorphism/0DESCRIPTION
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
[[wp:Parametric Polymorphism|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.
|
||||
|
||||
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.
|
||||
4
Task/Parametric-polymorphism/1META.yaml
Normal file
4
Task/Parametric-polymorphism/1META.yaml
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
category:
|
||||
- Type System
|
||||
note: Basic language learning
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
generic
|
||||
type Element_Type is private;
|
||||
package Container is
|
||||
type Tree is tagged private;
|
||||
procedure Replace_All(The_Tree : in out Tree; New_Value : Element_Type);
|
||||
private
|
||||
type Node;
|
||||
type Node_Access is access Node;
|
||||
type Tree tagged record
|
||||
Value : Element_type;
|
||||
Left : Node_Access := null;
|
||||
Right : Node_Access := null;
|
||||
end record;
|
||||
end Container;
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
package body Container is
|
||||
procedure Replace_All(The_Tree : in out Tree; New_Value : Element_Type) is
|
||||
begin
|
||||
The_Tree.Value := New_Value;
|
||||
If The_Tree.Left /= null then
|
||||
The_Tree.Left.all.Replace_All(New_Value);
|
||||
end if;
|
||||
if The_tree.Right /= null then
|
||||
The_Tree.Right.all.Replace_All(New_Value);
|
||||
end if;
|
||||
end Replace_All;
|
||||
end Container;
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
template<class T>
|
||||
class tree
|
||||
{
|
||||
T value;
|
||||
tree *left;
|
||||
tree *right;
|
||||
public:
|
||||
void replace_all (T new_value);
|
||||
};
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
template<class T>
|
||||
void tree<T>::replace_all (T new_value)
|
||||
{
|
||||
value = new_value;
|
||||
left->replace_all (new_value);
|
||||
right->replace_all (new_value);
|
||||
}
|
||||
47
Task/Parametric-polymorphism/C/parametric-polymorphism.c
Normal file
47
Task/Parametric-polymorphism/C/parametric-polymorphism.c
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define decl_tree_type(T) \
|
||||
typedef struct node_##T##_t node_##T##_t, *node_##T; \
|
||||
struct node_##T##_t { node_##T left, right; T value; }; \
|
||||
\
|
||||
node_##T node_##T##_new(T v) { \
|
||||
node_##T node = malloc(sizeof(node_##T##_t)); \
|
||||
node->value = v; \
|
||||
node->left = node->right = 0; \
|
||||
return node; \
|
||||
} \
|
||||
node_##T node_##T##_insert(node_##T root, T v) { \
|
||||
node_##T n = node_##T##_new(v); \
|
||||
while (root) { \
|
||||
if (root->value < n->value) \
|
||||
if (!root->left) return root->left = n; \
|
||||
else root = root->left; \
|
||||
else \
|
||||
if (!root->right) return root->right = n; \
|
||||
else root = root->right; \
|
||||
} \
|
||||
return 0; \
|
||||
}
|
||||
|
||||
#define tree_node(T) node_##T
|
||||
#define node_insert(T, r, x) node_##T##_insert(r, x)
|
||||
#define node_new(T, x) node_##T##_new(x)
|
||||
|
||||
decl_tree_type(double);
|
||||
decl_tree_type(int);
|
||||
|
||||
int main()
|
||||
{
|
||||
int i;
|
||||
tree_node(double) root_d = node_new(double, (double)rand() / RAND_MAX);
|
||||
|
||||
for (i = 0; i < 10000; i++)
|
||||
node_insert(double, root_d, (double)rand() / RAND_MAX);
|
||||
|
||||
tree_node(int) root_i = node_new(int, rand());
|
||||
for (i = 0; i < 10000; i++)
|
||||
node_insert(int, root_i, rand());
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
::Tree a = Empty | Node a (Tree a) (Tree a)
|
||||
|
||||
mapTree :: (a -> b) (Tree a) -> (Tree b)
|
||||
mapTree f Empty = Empty
|
||||
mapTree f (Node x l r) = Node (f x) (mapTree f l) (mapTree f r)
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
instance Functor Tree where
|
||||
fmap f Empty = Empty
|
||||
fmap f (Node x l r) = Node (f x) (fmap f l) (fmap f r)
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
add1Everywhere :: (f a) -> (f a) | Functor f & Num a
|
||||
add1Everywhere nums = fmap (\x = x + 1) nums
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
(deftype pair (&key (car 't) (cdr 't))
|
||||
`(cons ,car ,cdr))
|
||||
46
Task/Parametric-polymorphism/D/parametric-polymorphism.d
Normal file
46
Task/Parametric-polymorphism/D/parametric-polymorphism.d
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
class ArrayTree(T, uint N) {
|
||||
T[N] data;
|
||||
typeof(this) left, right;
|
||||
|
||||
this(T initValue) { this.data[] = initValue; }
|
||||
|
||||
void tmap(const void delegate(ref typeof(data)) dg) {
|
||||
dg(this.data);
|
||||
if (left) left.tmap(dg);
|
||||
if (right) right.tmap(dg);
|
||||
}
|
||||
}
|
||||
|
||||
void main() { // Demo code.
|
||||
import std.stdio;
|
||||
|
||||
// Instantiate the template ArrayTree of three doubles.
|
||||
alias AT3 = ArrayTree!(double, 3);
|
||||
|
||||
// Allocate the tree root.
|
||||
auto root = new AT3(1.00);
|
||||
|
||||
// Add some nodes.
|
||||
root.left = new AT3(1.10);
|
||||
root.left.left = new AT3(1.11);
|
||||
root.left.right = new AT3(1.12);
|
||||
|
||||
root.right = new AT3(1.20);
|
||||
root.right.left = new AT3(1.21);
|
||||
root.right.right = new AT3(1.22);
|
||||
|
||||
// Now the tree has seven nodes.
|
||||
|
||||
// Show the arrays of the whole tree.
|
||||
//root.tmap(x => writefln("%(%.2f %)", x));
|
||||
root.tmap((ref x) => writefln("%(%.2f %)", x));
|
||||
|
||||
// Modify the arrays of the whole tree.
|
||||
//root.tmap((x){ x[] += 10; });
|
||||
root.tmap((ref x){ x[] += 10; });
|
||||
|
||||
// Show the arrays of the whole tree again.
|
||||
writeln();
|
||||
//root.tmap(x => writefln("%(%.2f %)", x));
|
||||
root.tmap((ref x) => writefln("%(%.2f %)", x));
|
||||
}
|
||||
31
Task/Parametric-polymorphism/E/parametric-polymorphism-1.e
Normal file
31
Task/Parametric-polymorphism/E/parametric-polymorphism-1.e
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
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
|
||||
}
|
||||
11
Task/Parametric-polymorphism/E/parametric-polymorphism-2.e
Normal file
11
Task/Parametric-polymorphism/E/parametric-polymorphism-2.e
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
? def t := makeTree(int, 0, null, null)
|
||||
# value: <tree>
|
||||
|
||||
? t :Tree[String]
|
||||
# problem: Tree value type mismatch
|
||||
|
||||
? t :Tree[Int]
|
||||
# problem: Failed: Undefined variable: Int
|
||||
|
||||
? t :Tree[int]
|
||||
# value: <tree>
|
||||
53
Task/Parametric-polymorphism/Go/parametric-polymorphism.go
Normal file
53
Task/Parametric-polymorphism/Go/parametric-polymorphism.go
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func average(c intCollection) float64 {
|
||||
var sum, count int
|
||||
c.mapElements(func(n int) {
|
||||
sum += n
|
||||
count++
|
||||
})
|
||||
return float64(sum) / float64(count)
|
||||
}
|
||||
|
||||
func main() {
|
||||
t1 := new(binaryTree)
|
||||
t2 := new(bTree)
|
||||
a1 := average(t1)
|
||||
a2 := average(t2)
|
||||
fmt.Println("binary tree average:", a1)
|
||||
fmt.Println("b-tree average:", a2)
|
||||
}
|
||||
|
||||
type intCollection interface {
|
||||
mapElements(func(int))
|
||||
}
|
||||
|
||||
type binaryTree struct {
|
||||
// dummy representation details
|
||||
left, right bool
|
||||
}
|
||||
|
||||
func (t *binaryTree) mapElements(visit func(int)) {
|
||||
// dummy implementation
|
||||
if t.left == t.right {
|
||||
visit(3)
|
||||
visit(1)
|
||||
visit(4)
|
||||
}
|
||||
}
|
||||
|
||||
type bTree struct {
|
||||
// dummy representation details
|
||||
buckets int
|
||||
}
|
||||
|
||||
func (t *bTree) mapElements(visit func(int)) {
|
||||
// dummy implementation
|
||||
if t.buckets >= 0 {
|
||||
visit(1)
|
||||
visit(5)
|
||||
visit(9)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
data Tree a = Empty | Node a (Tree a) (Tree a)
|
||||
|
||||
mapTree :: (a -> b) -> Tree a -> Tree b
|
||||
mapTree f Empty = Empty
|
||||
mapTree f (Node x l r) = Node (f x) (mapTree f l) (mapTree f r)
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
instance Functor Tree where
|
||||
fmap f Empty = Empty
|
||||
fmap f (Node x l r) = Node (f x) (fmap f l) (fmap f r)
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
add1Everywhere :: (Functor f, Num a) => f a -> f a
|
||||
add1Everywhere nums = fmap (\x -> x + 1) nums
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
Polymorphism is a room.
|
||||
|
||||
To find (V - K) in (L - list of values of kind K):
|
||||
repeat with N running from 1 to the number of entries in L:
|
||||
if entry N in L is V:
|
||||
say "Found [V] at entry [N] in [L].";
|
||||
stop;
|
||||
say "Did not find [V] in [L]."
|
||||
|
||||
When play begins:
|
||||
find "needle" in {"parrot", "needle", "rutabaga"};
|
||||
find 6 in {2, 3, 4};
|
||||
end the story.
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
list of numbers
|
||||
relation of texts to rooms
|
||||
object based rulebook producing a number
|
||||
description of things
|
||||
activity on things
|
||||
number valued property
|
||||
text valued table column
|
||||
phrase (text, text) -> number
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
public class Tree<T>{
|
||||
private T value;
|
||||
private Tree<T> left;
|
||||
private Tree<T> right;
|
||||
|
||||
public void replaceAll(T value){
|
||||
this.value = value;
|
||||
if(left != null)
|
||||
left.replaceAll(value);
|
||||
if(right != null)
|
||||
right.replaceAll(value);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
type 'a tree = Empty | Node of 'a * 'a tree * 'a tree
|
||||
|
||||
(** val map_tree : ('a -> 'b) -> 'a tree -> 'b tree *)
|
||||
let rec map_tree f = function
|
||||
| Empty -> Empty
|
||||
| Node (x,l,r) -> Node (f x, map_tree f l, map_tree f r)
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
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);
|
||||
$.right.?replace-all($value);
|
||||
}
|
||||
}
|
||||
|
||||
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.perl;
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
(de mapTree (Tree Fun)
|
||||
(set Tree (Fun (car Tree)))
|
||||
(and (cadr Tree) (mapTree @ Fun))
|
||||
(and (cddr Tree) (mapTree @ Fun)) )
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
#lang typed/racket
|
||||
|
||||
(define-type (Tree A) (U False (Node A)))
|
||||
|
||||
(struct: (A) Node
|
||||
([val : A] [left : (Tree A)] [right : (Tree A)])
|
||||
#:transparent)
|
||||
|
||||
(: tree-map (All (A B) (A -> B) (Tree A) -> (Tree B)))
|
||||
(define (tree-map f tree)
|
||||
(match tree
|
||||
[#f #f]
|
||||
[(Node val left right)
|
||||
(Node (f val) (tree-map f left) (tree-map f right))]))
|
||||
|
||||
;; unit tests
|
||||
(require typed/rackunit)
|
||||
(check-equal?
|
||||
(tree-map add1 (Node 5 (Node 3 #f #f) #f))
|
||||
(Node 6 (Node 4 #f #f) #f))
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
case class Tree[+A](value: A, left: Option[Tree[A]], right: Option[Tree[A]]) {
|
||||
def map[B](f: A => B): Tree[B] =
|
||||
Tree(f(value), left map (_.map(f)), right map (_.map(f)))
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
class Employee(val name: String)
|
||||
class Manager(name: String) extends Employee(name)
|
||||
|
||||
val t = Tree(new Manager("PHB"), None, None)
|
||||
val t2: Tree[Employee] = t
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
def toName(e: Employee) = e.name
|
||||
val treeOfNames = t.map(toName)
|
||||
|
|
@ -0,0 +1 @@
|
|||
trait Function1[-T1, +R]
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
case class Tree[+A](value: A, left: Option[Tree[A]], right: Option[Tree[A]]) {
|
||||
def map[B](f: A => B): Tree[B] =
|
||||
Tree(f(value), left map (_.map(f)), right map (_.map(f)))
|
||||
def find[B >: A](what: B): Boolean =
|
||||
(value == what) || left.map(_.find(what)).getOrElse(false) || right.map(_.find(what)).getOrElse(false)
|
||||
}
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
if (t2.find(new Employee("Dilbert")))
|
||||
println("Call Catbert!")
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
trait DFA {
|
||||
type Element
|
||||
val map = new collection.mutable.HashMap[Element, DFA]()
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
$ include "seed7_05.s7i";
|
||||
|
||||
const func type: container (in type: elemType) is func
|
||||
result
|
||||
var type: container is void;
|
||||
begin
|
||||
container := array elemType;
|
||||
|
||||
global
|
||||
|
||||
const func container: map (in container: aContainer,
|
||||
inout elemType: aVariable, ref func elemType: aFunc) is func
|
||||
result
|
||||
var container: mapResult is container.value;
|
||||
begin
|
||||
for aVariable range aContainer do
|
||||
mapResult &:= aFunc;
|
||||
end for;
|
||||
end func;
|
||||
|
||||
end global;
|
||||
end func;
|
||||
|
||||
const type: intContainer is container(integer);
|
||||
var intContainer: container1 is [] (1, 2, 4, 6, 10, 12, 16, 18, 22);
|
||||
var intContainer: container2 is 0 times 0;
|
||||
|
||||
const proc: main is func
|
||||
local
|
||||
var integer: num is 0;
|
||||
begin
|
||||
container2 := map(container1, num, num + 1);
|
||||
for num range container2 do
|
||||
write(num <& " ");
|
||||
end for;
|
||||
writeln;
|
||||
end func;
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
datatype 'a tree = Empty | Node of 'a * 'a tree * 'a tree
|
||||
|
||||
(** val map_tree = fn : ('a -> 'b) -> 'a tree -> 'b tree *)
|
||||
fun map_tree f Empty = Empty
|
||||
| map_tree f (Node (x,l,r)) = Node (f x, map_tree f l, map_tree f r)
|
||||
|
|
@ -0,0 +1 @@
|
|||
binary_tree_of "node-type" = "node-type"%hhhhWZAZ
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
#import tag
|
||||
|
||||
#fix general_type_fixer 1
|
||||
|
||||
binary_tree_of "node-type" = ("node-type",(binary_tree_of "node-type")%Z)%drWZwlwAZ
|
||||
|
|
@ -0,0 +1 @@
|
|||
binary_tree_of = %-hhhhWZAZ
|
||||
|
|
@ -0,0 +1 @@
|
|||
binary_tree_map "f" = ~&a^& ^A/"f"@an ~&amPfamPWB
|
||||
|
|
@ -0,0 +1 @@
|
|||
binary_tree_map = ~&a^&+ ^A\~&amPfamPWB+ @an
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
string_tree = binary_tree_of %s
|
||||
|
||||
x = 'foo': ('bar': (),'baz': ())
|
||||
|
||||
#cast string_tree
|
||||
|
||||
example = (binary_tree_map "s". "s"--"s") x
|
||||
Loading…
Add table
Add a link
Reference in a new issue