tasks a-s

This commit is contained in:
Ingy döt Net 2013-04-10 23:57:08 -07:00
parent 47bf37c096
commit b83f433714
12433 changed files with 156208 additions and 123 deletions

View 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.

View file

@ -0,0 +1,4 @@
---
category:
- Type System
note: Basic language learning

View file

@ -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;

View file

@ -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;

View file

@ -0,0 +1,9 @@
template<class T>
class tree
{
T value;
tree *left;
tree *right;
public:
void replace_all (T new_value);
};

View file

@ -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);
}

View 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;
}

View file

@ -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)

View file

@ -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)

View file

@ -0,0 +1,2 @@
add1Everywhere :: (f a) -> (f a) | Functor f & Num a
add1Everywhere nums = fmap (\x = x + 1) nums

View file

@ -0,0 +1,2 @@
(deftype pair (&key (car 't) (cdr 't))
`(cons ,car ,cdr))

View 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));
}

View 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
}

View 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>

View 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)
}
}

View file

@ -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)

View file

@ -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)

View file

@ -0,0 +1,2 @@
add1Everywhere :: (Functor f, Num a) => f a -> f a
add1Everywhere nums = fmap (\x -> x + 1) nums

View file

@ -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.

View file

@ -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

View file

@ -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);
}
}

View file

@ -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)

View file

@ -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;

View file

@ -0,0 +1,4 @@
(de mapTree (Tree Fun)
(set Tree (Fun (car Tree)))
(and (cadr Tree) (mapTree @ Fun))
(and (cddr Tree) (mapTree @ Fun)) )

View file

@ -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))

View file

@ -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)))
}

View file

@ -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

View file

@ -0,0 +1,2 @@
def toName(e: Employee) = e.name
val treeOfNames = t.map(toName)

View file

@ -0,0 +1 @@
trait Function1[-T1, +R]

View file

@ -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)
}

View file

@ -0,0 +1,2 @@
if (t2.find(new Employee("Dilbert")))
println("Call Catbert!")

View file

@ -0,0 +1,4 @@
trait DFA {
type Element
val map = new collection.mutable.HashMap[Element, DFA]()
}

View file

@ -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;

View file

@ -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)

View file

@ -0,0 +1 @@
binary_tree_of "node-type" = "node-type"%hhhhWZAZ

View file

@ -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

View file

@ -0,0 +1 @@
binary_tree_of = %-hhhhWZAZ

View file

@ -0,0 +1 @@
binary_tree_map "f" = ~&a^& ^A/"f"@an ~&amPfamPWB

View file

@ -0,0 +1 @@
binary_tree_map = ~&a^&+ ^A\~&amPfamPWB+ @an

View file

@ -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