In this section, we describe how we can define our own user defined types in Ocaml. There are two primary ways to go about this - using variants, and using records.
Variants
In Ocaml, a variant is a datatype representing a value that can be one of several possibilities. Variants in Ocaml are analogous to enumerators in other languages.
To define a variant, we use the type keyword followed by a | delimited list of possible values. We can also assign data to a variant possibility by using the of keyword, followed by the type to assign.
(* define a variant *)
type [Type] = [Value1] | [Value2] | ... | [ValueX]
 
(* define a variant Coin which can either be Heads or Tails *)
type coin = Heads | Tails
(* define a variant Color, which can be Red, Green, or Blue,
   each with an associated integer value *)
type color = Red of int | Blue of int | Green of int ;;Variant types must begin with a lowercase letter.
Note that we can use a variant in its own definition! This can be used to create recursive data structures, which may be useful in creating LinkedLists, Trees, and more.
type tree = Node of int * tree * tree | Leaf ;;
type lst = List of int * lst | ListEnd ;;To assign a variable to a variant type, we use the name of a variant possibility, followed by a value if that possibility has associated data.
let a = Heads ;; (* a is Heads of type coin *)
let b = Tails ;; (* b is Tails of type coin *)
 
let r = Red(3) ;; (* r is Red with value 3, of type color *)
let g = Green ;;  (* INVALID - Green has associated data *)Variants can be used in pattern matching operations! To pattern match with a variant, we list the variant’s possibilities as patterns to match with.
(* match variable of type coin *)
let _ = match a with
    | Heads -> print_string "Heads!"
    | Tails -> print_string "Tails!" ;;
 
(* match variable of type color *)
let _ = match r with
    | Red(x) -> x
    | Green(y) -> y
    | Blue(z) -> z ;;Example: Variants
Below, we create a variant of type
treerepresenting a Tree datastructure, and define a function to recurse through it using inorder traversal.type tree = Tree of int * tree * tree | Leaf ;; let rec print_all t = match t with | Tree (v, left, right) -> let _ = print_all left in let _ = print_int v in print_all right | Leaf -> ()
Records
Another way to define a new type is Ocaml is to use records, which represents a composite of other data types, where each type has an associated name. Records in Ocaml are analogous to structures in other languages.
To define a record, we use the type keyword, followed by a ; delimited list of Name: Type pairs, denoting a particular field of the record, and its type.
type <record-name> =
    { <field> : <type>;
      <field> : <type>;
      ...
    }
 
type player =
     {
        health: int;
        defense: int;
        attack: int;
     } ;;Then, to create an instance of a type, we use braces { } containing a ; delimited list of Field = Value pairs, assigning a value to each field of the record. Then, to access fields of the instance, we can use the . operator.
let p1 =
    {
       health = 1;
       defense = 2;
       attack = 10;
    } ;; 
 
let h = p1.health ;;  (* h is 1 *)
let d = p1.defense ;; (* d is 2 *)
let a = p1.attack ;;  (* a is 10 *)To define a record with generic types, we need to specify what generic types are to be used in the record, before it’s name.
type ('a, 'b) graph =
     {
        var1 : 'a ;
        var2 : 'b ;
     } ;;