package higher_kinded

  1. Overview
  2. Docs

This library allows you to use higher-kinded types in OCaml. See the README for a short tutorial on what that means and how to use it.

Types

type ('a, 'witness) t

If A implements the signature S, (a, A.witness1) t is equivalent to a A.t.

type ('a, 'b, 'witness) t2 = ('a, ('b, 'witness) t) t

If A implements the signature S2, (a, b, A.witness2) t2 is equivalent to (a, b) A.t.

type ('a, 'b, 'c, 'witness) t3 = ('a, 'b, ('c, 'witness) t) t2

If A implements the signature S3, (a, b, c, A.witness3) t3 is equivalent to (a, b, c) A.t.

type ('a, 'b, 'c, 'd, 'witness) t4 = ('a, 'b, 'c, ('d, 'witness) t) t3

If A implements the signature S4, (a, b, c, d, A.witness4) t4 is equivalent to (a, b, c, d) A.t.

type ('a, 'b, 'c, 'd, 'e, 'witness) t5 = ('a, 'b, 'c, 'd, ('e, 'witness) t) t4

If A implements the signature S5, (a, b, c, d, e, A.witness5) t5 is equivalent to (a, b, c, d, e) A.t.

type ('a, 'b, 'c, 'd, 'e, 'f, 'witness) t6 = ('a, 'b, 'c, 'd, 'e, ('f, 'witness) t) t5

If A implements the signature S6, (a, b, c, d, e, f, A.witness6) t6 is equivalent to (a, b, c, d, e, f) A.t.

type ('a, 'b, 'c, 'd, 'e, 'f, 'g, 'witness) t7 = ('a, 'b, 'c, 'd, 'e, 'f, ('g, 'witness) t) t6

If A implements the signature S7, (a, b, c, d, e, f, g, A.witness7) t7 is equivalent to (a, b, c, d, e, f, g) A.t.

type ('a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'witness) t8 = ('a, 'b, 'c, 'd, 'e, 'f, 'g, ('h, 'witness) t) t7

If A implements the signature S8, (a, b, c, d, e, f, g, h, A.witness8) t8 is equivalent to (a, b, c, d, e, f, g, h) A.t.

Signatures

These are the signatures implemented by the Make family of functors.

module type S = sig ... end
module type S2 = sig ... end
module type S3 = sig ... end
module type S4 = sig ... end
module type S5 = sig ... end
module type S6 = sig ... end
module type S7 = sig ... end
module type S8 = sig ... end

Functors

This is the meat of the library. Use these functors to implement the higher_kinded interface.

module Make (X : Base.T1) : S with type 'a t := 'a X.t
module Make2 (X : Base.T2) : S2 with type ('a, 'z) t := ('a, 'z) X.t
module Make3 (X : Base.T3) : S3 with type ('a, 'y, 'z) t := ('a, 'y, 'z) X.t
module Make4 (X : sig ... end) : S4 with type ('a, 'x, 'y, 'z) t := ('a, 'x, 'y, 'z) X.t
module Make5 (X : sig ... end) : S5 with type ('a, 'w, 'x, 'y, 'z) t := ('a, 'w, 'x, 'y, 'z) X.t
module Make6 (X : sig ... end) : S6 with type ('a, 'v, 'w, 'x, 'y, 'z) t := ('a, 'v, 'w, 'x, 'y, 'z) X.t
module Make7 (X : sig ... end) : S7 with type ('a, 'u, 'v, 'w, 'x, 'y, 'z) t := ('a, 'u, 'v, 'w, 'x, 'y, 'z) X.t
module Make8 (X : sig ... end) : S8 with type ('a, 't, 'u, 'v, 'w, 'x, 'y, 'z) t := ('a, 't, 'u, 'v, 'w, 'x, 'y, 'z) X.t

Implementations

Base, Core, and Async don't depend on Higher_kinded, so we put these implementations here instead of in the respective modules where they might have been a nicer fit.

module Ident : S with type 'a t := 'a
module Array : S with type 'a t := 'a Base.Array.t
module Either : S2 with type ('a, 'b) t := ('a, 'b) Base.Either.t
module Hash_set : S with type 'a t := 'a Base.Hash_set.t
module Hashtbl : S2 with type ('a, 'b) t := ('a, 'b) Base.Hashtbl.t
module Lazy : S with type 'a t := 'a Base.Lazy.t
module List : S with type 'a t := 'a Base.List.t
module Map : S3 with type ('a, 'b, 'c) t := ('a, 'b, 'c) Base.Map.t
module Option : S with type 'a t := 'a Base.Option.t
module Queue : S with type 'a t := 'a Base.Queue.t
module Ref : S with type 'a t := 'a Base.Ref.t
module Result : S2 with type ('a, 'e) t := ('a, 'e) Base.Result.t
module Set : S2 with type ('a, 'b) t := ('a, 'b) Base.Set.t
module Sequence : S with type 'a t := 'a Base.Sequence.t
module Type_equal : S2 with type ('a, 'b) t := ('a, 'b) Base.Type_equal.t

t itself has two type parameters, so we might as well implement S2 right here.

include S2 with type ('a, 'witness) t := ('a, 'witness) t
type witness2
type 'z witness1 = ('z, witness2) t
type ('a, 'z) witness = ('a, 'z witness1) t
val inject : ('a, 'z) t -> ('a, 'z) witness
val project : ('a, 'z) witness -> ('a, 'z) t