1.23. Generic Functions

Felix functions and procedures can be generic too. Here is a simple example.
Start C++ section to tut/examples/tut135a.flx[1 /1 ]
     1: header "#include <iostream>";
     2: type int = "int";
     3: proc print[T]:T="std::cout << $1 << std::endl;";
     4: fun fst[T,U](x:T,y:U): T ={ return x; }
     5: fun snd[T,U](x:T,y:U): U ={ return y; }
     6: 
     7: val x = (1,2);
     8: print[int] (fst[int,int] x);
     9: print[int] (snd[int,int] x);
    10: 
    11: proc pp[T] (x:T) { print[T](x); }
    12: 
    13: pp[int] (snd[int,int] x);
    14: 
End C++ section to tut/examples/tut135a.flx[1]
When declaring a generic function or procedure, if one of the parameters has the type of a type variable which is not used elsewhere, you can leave out the type variable, and one will be synthesised for you. Synthesised type variables are added to the type variable list at the end. For example:
Start C++ section to tut/examples/tut135b.flx[1 /1 ]
     1: header "#include <iostream>";
     2: type int = "int";
     3: proc print[T]:T="std::cout << $1 << std::endl;";
     4: fun fst(x,y) = { return x; }
     5: fun snd(x,y) = { return y; }
     6: 
     7: val x = (1,2);
     8: print[int] (fst[int,int] x);
     9: print[int] (snd[int,int] x);
    10: 
    11: proc pp[T] (x:T) { print[T](x); }
    12: 
    13: pp[int] (snd[int,int] x);
    14: 
End C++ section to tut/examples/tut135b.flx[1]
Note in this example, the return type cannot be stated since it depends on a synthesised type variable.

When there is only one argument which has a type which is a type variable, then if the type variable is omitted, the parentheses can also be omitted. This is particularly useful with curried declarations.

Note carefully that in the call to pair below, both the type subscripts must be given explicity, because they cannot be deduced from the argument.

Start C++ section to tut/examples/tut135c.flx[1 /1 ]
     1: include "std";
     2: fun pair1 x y = { return x,y; }
     3: fun pair2[t,u] (x:t) (y:u) = { return x,y; }
     4: fun diag x = { return x,x; }
     5: fun fst (x,y) = { return x; }
     6: fun snd (x,y) = { return y; }
     7: 
     8: {
     9:   val x34 = pair1[int,int] 3 4;
    10:   val a = fst x34;
    11:   val b = snd x34;
    12:   print a; print ","; print b; endl;
    13: };
    14: 
    15: {
    16:   val x34 = pair2[int,int] 3 4;
    17:   val a = fst x34;
    18:   val b = snd x34;
    19:   print a; print ","; print b; endl;
    20: };
    21: 
    22: val x22 = diag 2;
    23: val x = fst x22;
    24: val y = snd x22;
    25: print x; print ","; print y; endl;
    26: 
End C++ section to tut/examples/tut135c.flx[1]