What is a Variant int he context of types in OCAML?

What does the term Variant mean in OCAML?

It means what people refer to as sum types, or discriminated unions, or algebraic data types. You can read up on them here: https://v1.realworldocaml.org/v1/en/html/variants.html

So Variant’s are just “custom types”? I don’t see why such a fancy name for a concept that seems normal? Or am I not appreciating something? It feels like I don’t appreciate something…

There are custom types that are not variants, and I am not sure that all variants are custom types: typically, bool, 'a list, 'a option, ('a, 'b) result are variant types, and I don’t know whether we want to consider them custom or not.

There are two ways for defining new types from existing ones: either by making sums of types or by making products of types.

  • Variants, sum types, discriminated unions are different names for the same concept, that is types whose values are built by selecting (varying?) one constructor among the constructors allowed for that type (these types are the sums of the types which compose them).
  • By opposition, tuples and records are not variants (these types are the products of the types which compose them).

Algebraic data types are the types obtained by sums and products. There are custom types that are not algebraic, for instance abstract types. I think that we don’t consider arrow types to be algebraic neither.

Well ‘custom type’ is also a name that someone came up with and it’s not actually a common name for the concept. In most other languages you will find the names that I mentioned previously.

so variants are custom types or not?

Not sure what you call a “custom type”, but if by that you mean “user-defined”, then no. The user can define some variants, others (like bool) are defined directly in the OCaml language.

What is your definition of ‘custom type’?

I assume you’re coming from OOP languages. If so, what you need to understand is that there are only so many ways to create new types. A language has its primitive types (int, float, bool). It may then have a record type that aggregates those types together, while giving them a new name (type foo = {foo: int; bar: bool}). You’re probably also used to object oriented types, which involve classes and inheritance. Notice that this is a very specific way of extending types called subtyping: you have your basic class, which is a record where some of the fields can be functions (methods) that take self as an implicit parameter, and you create subtypes with different names that include the base type but also some new methods and fields.

A different way of extending types is using or rather than and. Records say a type must have field x and field y etc. Sum types say a type can have fields x and y or it can have type bool or it can have a tuple of floats etc. To choose which option of the sum type you wish to have at any point in time, you use the specific variant’s constructor. e.g.

type foo = Name of string
              | Age of int
              | Date of {year: int; month: int; day: int}

The three choices in sum type foo cannot coexist. Only one of them can be active at a time. Each of the choices is called a variant, and their respective constructor is the capitalized word that precedes the content of the type (Name/Age/Date).

1 Like