Skip to main content
Version: 1.6.0

Functions

Polymorphic functions accept arguments of parametric types, that is, a larger category of inputs, as long as the function does not assume a particular type for the argument (so called uniform polymorphism).

Perhaps the most trivial example is the identity function.

For any given type t, there is a canonical function from type t to type t: it takes an argument and returns it immediately. For instance, we can write the identity function for int as follows:

const id_int = (x: int) : int => x;

However, if we would want to use the same function on a different type, such as nat, we will need to write a new definition:

const id_nat = (x : nat) : nat => x;

If we read carefully, we see that there is almost no difference between id_int and id_nat: it is just the type that changes, but for the rest, the body of the function remains the same.

Thanks to parametric polymorphism, we can write a single function declaration that works for both cases.

const id = <T>(x: T) : T => x;

Here T is a type variable which can be generalised. If we have more than one type parameter, we list them like so:

const map = <A,B>(f: (x:A) => B, l: list<A>) : list<B> => List.map (f,l);

We can now call the function id with arguments of different types:

const three_int : int = id(3);
const three_string : string = id("three");

During compilation, LIGO will monomorphise the polymorphic functions into specific instances, resulting in Michelson code that does not contain polymorphic function declarations anymore.