July 28th, 2024

Higher-kinded bounded polymorphism in OCaml

Higher-kinded bounded polymorphism is crucial for generic operations and DSLs. OCaml lacks direct support but can simulate it through its module system, leading to complex and verbose code.

Read original articleLink Icon
Higher-kinded bounded polymorphism in OCaml

Higher-kinded bounded polymorphism allows for abstraction over type constructors, which is essential for creating generic operations on collections and embedding typed domain-specific languages (DSLs). OCaml does not directly support higher-kinded polymorphism, as its type variables are limited to types rather than type constructors. However, it is possible to express higher-kinded polymorphism in OCaml through various methods, albeit in cumbersome ways. The article discusses the concept of bounded polymorphism, where type constructors must adhere to specific interfaces, using examples such as summing numbers in lists and the implementation of a monoid structure.

The text explains that while OCaml lacks higher-kind type variables, it can still achieve similar functionality through its module system and functors. This approach, however, leads to verbose and awkward code. The authors, Yallop and White, propose that higher-kinded polymorphism can be reduced to ordinary polymorphism through a technique called defunctionalization, which involves representing parameterized types in a different form. The article illustrates this with the example of lists, showing how to create a bijection between the list type and a new representation that allows for abstraction over the base name of the type.

In summary, while OCaml does not natively support higher-kinded polymorphism, it can be simulated through various techniques, albeit with increased complexity and verbosity in code.

Link Icon 4 comments
By @skulk - 10 months
> Thus, with type aliases, the type equality problem becomes the higher-order unification problem, which is not decidable.

I wonder how much this is a problem in practice, aside from the type-checker taking too long.

By @munchler - 10 months
I'm more familiar with F#, so I got stuck at this line:

    type ('a,'b) app += List_name : 'a list -> ('a,list_name) app
I understand that app is an extensible type and this line adds a union case called List_name to the type, but the signature of List_name confuses me. If I write (List_name x) is x a list or a function?
By @tempodox - 9 months
This article is pure gold. Rarely is this stuff explained so well.