1.25. Argument Deduction

It is inconvenient to specify the type arguments for a function. Generally, this is not necessary, as illustrated in the example: Felix deduces the value of the type variables from function arguments.
Start C++ section to tut/examples/tut135f.flx[1 /1 ]
     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: 
End C++ section to tut/examples/tut135f.flx[1]