1: include "std"; 2: union list[T] = 3: | Cons of T * list[T] 4: | Empty 5: ; 6: 7: struct pair[T,U] = 8: { 9: fst : T; 10: snd : U; 11: } 12: 13: var x = Cons (1,Empty[int]); 14: // the [int] in Empty is mandatory 15: 16: x = Cons(2,x); 17: x = Cons(3,x); 18: 19: fun f[t] (x:list[t]):list[t] = { return x; } 20: 21: x = f(x); 22: 23: val y = pair(1,2); 24: print y.fst; print ","; print y.snd; endl; 25: 26: 27: // check nested generics now 28: 29: module F[T] { 30: fun id1(x:T):T = { return x; } 31: } 32: 33: print (F[int]::id1 1); endl; 34: 35: module A[T] { 36: module B[U] { 37: fun id2[V](x:T,y:U,z:V):V*U*T = { return z,y,x; } 38: } 39: } 40: 41: val zyx = (A[int]::B[int]::id2(1,2,3)); 42: print zyx.(0); 43: print zyx.(1); 44: print zyx.(2); 45: endl; 46: 47: // check specialisation 48: fun idt[T] (x:T):T*T = { return x,x; } 49: fun idt[T] (x:T*T):T*T = { return x; } 50: 51: val x1 = idt(1); // calls first idt 52: val x2 = idt(1,2); // calls second idt 53: print x1.(0); print x1.(1); endl; // print 11 54: print x2.(0); print x2.(1); endl; // print 12 55: 56: proc pr[T] (x:list[T], pp:T->void) { 57: match x with 58: | Cons (?i,?t) => { pp i; pr (t,pp); } 59: | Empty => { print "Empty"; } 60: endmatch 61: ; 62: } 63: 64: proc printint (x:int) { print x; } 65: // because we can't use a primitive as a closure yet 66: 67: pr (x,(printint of (int))); endl; 68: