In OCaml, recursive types are types that are defined in terms of themselves. One common example is the definition of natural numbers using the nat type.

type nat = Z | S of nat

In this example, the nat type is defined as a variant type with two constructors: Z for zero, and S for the successor of a natural number. The S constructor takes a nat as an argument, hence the type nat is defined in terms of itself. This allows us to represent the infinite set of natural numbers using this type.

To represent the natural number 5 using the nat type, we can use the S constructor multiple times. Since the S constructor takes a nat as an argument and represents the successor of a natural number, we can create a chain of S constructors to represent the number 5.

let five : nat = S (S (S (S (S Z))))

You can use pattern matching to match against the constructors of a recursive type and perform different actions depending on the variant. For example, you can write a function that takes a nat and returns an integer:

let rec nat_to_int (n:nat) =
  match n with
  | Z -> 0
  | S n' -> 1 + nat_to_int n'

In this example, the function nat_to_int takes a variable n of type nat and uses pattern matching to match n against the constructors of the nat type. If n is Z, the function returns 0, if it is S n' the function adds 1 to the result of the nat_to_int applied to n'. This way, the function is able to traverse the recursive definition of the nat type and convert it to an integer value.

It’s worth noting that recursive types are a powerful feature of OCaml, they allow to model a wide range of data structures and algorithms, they are also used to express types that are infinite in nature such as natural numbers, lists and many more. They are very useful in functional programming and functional languages like OCaml.