package irmin

  1. Overview
  2. Docs
Irmin, a distributed database that follows the same design principles as Git

Install

Dune Dependency

Authors

Maintainers

Sources

irmin-2.10.0.tbz
sha256=58b4d058252fc3fca27aa4704594758ea17b5b549076495b53dea7217bd6e64a
sha512=3f7d7817b708d2be41bf81fb7c8f637e0331cc73ffc49d54ae809982d5f258f62255c892ed22c58688034ffa0aa7d32cb7fadb1b188a22ff0ddf80352da3d28b

doc/README_PPX.html

ppx_irmin

PPX extension for automatically generating Irmin type representations.

Overview

ppx_irmin automatically generates Irmin type representations (values of type _ Irmin.Type.t) corresponding to type declarations in your code. For example:

type 'a tree =
  | Branch of tree * bool option * tree
  | Leaf of 'a [@@deriving irmin]

will be expanded to:

type 'a tree = (* as above *)

let tree_t leaf_t =
  let open Irmin.Type in
  mu (fun tree_t ->
      variant "tree" (fun branch leaf -> function
          | Branch (x1, x2, x3) -> branch (x1, x2, x3)
          | Leaf   (x1, x2)     -> leaf (x1, x2))
      |~ case1 "Branch" (triple tree_t (option bool) tree_t) (fun (x1, x2, x3) -> Branch (x1, x2, x3))
      |~ case1 "Leaf"   leaf_t                               (fun x1 -> Leaf x1)
      |> sealv)

Type representations can also be derived inline using the [%typ: <core-type>] extension point.

Installation and usage

ppx_irmin may be installed via opam:

opam install ppx_irmin

If you're using the dune build system, add the following field to your library, executable or test stanza:

(preprocess (pps ppx_irmin))

You can now use [@@deriving irmin] after a type declaration in your code to automatically derive an Irmin type representation with the same name.

Specifics

ppx_irmin supports all of the type combinators exposed in the Irmin.Type module (basic types, records, variants (plain and closed polymorphic), recursive types etc.). Types with parameters will result in parameterised representations (i.e. type 'a t is generated a representation of type 'a Type.t -> 'a t Type.t).

To supply base representations from a module other than Irmin.Type (such as when Irmin.Type is aliased to a different module path), the lib argument can be passed to @@deriving irmin:

type foo = unit [@@deriving irmin { lib = Some "Mylib.Types" }]

(* generates the value *)
val foo_t = Mylib.Types.unit

This argument can also be passed as a command-line option (i.e. --lib Mylib.Types, with --lib '' interpreted as the current module).

Naming scheme

The generated type representation will be called <type-name>_t, unless the type-name is t, in which case the representation is simply t. This behaviour can be overridden using the name argument, as in:

type foo = string list * int32 [@@deriving irmin { name = "foo_repr" }]

(* generates the value *)
val foo_repr = Irmin.Type.(pair (list string) int32)

If the type contains an abstract type, ppx_irmin will expect to find a corresponding type representation using its own naming rules. This can be overridden using the [@repr ...] attribute, as in:

type bar = (foo [@repr foo_repr], string) result [@@deriving irmin]

(* generates the value *)
val bar_t = Irmin.Type.(result foo_repr string)

Built-in abstract types such as unit are assumed to be represented in Irmin.Type. This behaviour can be overridden with the [@nobuiltin] attribute:

type t = unit [@nobuiltin] [@@deriving irmin]

(* generates the value *)
let t = unit_t (* not [Irmin.Type.unit] *)
Signature type definitions

The ppx_irmin deriver can also be used in signatures to expose the auto-generated value:

module Contents : sig
  type t = int32 [@@deriving irmin]

  (* exposes repr in signature *)
  val t : t Irmin.Type.t

end = struct
  type t = int32 [@@deriving irmin]

  (* generates repr value *)
  val t = Irmin.Type.int32
end
OCaml

Innovation. Community. Security.