package ppx_variants_conv

  1. Overview
  2. Docs
Generation of accessor and iteration functions for ocaml variant types

Install

Dune Dependency

Authors

Maintainers

Sources

v0.11.1.tar.gz
sha256=57dab7570c46b464ce61424af363ad2d81dc0af82b64e3befa62de20f9431953
md5=146b49b84315b7d67c1ca758fcbf2fb2

Description

Part of the Jane Street's PPX rewriters collection.

Published: 14 May 2018

README

ppx_variants_conv

Generation of accessor and iteration functions for ocaml variant types.

ppx_variants_conv is a ppx rewriter that can be used to define first class values representing variant constructors, and additional routines to fold, iterate and map over all constructors of a variant type.

It provides corresponding functionality for variant types as ppx_fields_conv provides for record types.

Basic use of [@@deriving variants] and variantslib

This code:

type 'a t =
  | A of 'a
  | B of char
  | C
  | D of int * int
  [@@deriving variants]

generates the following values:

(** first-class constructor functions *)
val a : 'a -> 'a t
val b : char -> 'a t
val c : 'a t
val d : int -> int -> 'a t

(** higher order variants and functions over all variants *)
module Variants : sig
  val a : ('a -> 'a t)         Variant.t
  val b : (char -> 'a t)       Variant.t
  val c : ('a t)               Variant.t
  val d : (int -> int -> 'a t) Variant.t

  val fold :
    init: 'b
    -> a:('b -> ('a -> 'a t)         Variant.t -> 'c)
    -> b:('c -> (char -> 'a t)       Variant.t -> 'd)
    -> c:('d -> ('a t)               Variant.t -> 'e)
    -> d:('e -> (int -> int -> 'a t) Variant.t -> 'f)
    -> 'f

  val iter :
       a: (('a -> 'a t)         Variant.t -> unit)
    -> b: ((char -> 'a t)       Variant.t -> unit)
    -> c: (('a t)               Variant.t -> unit)
    -> d: ((int -> int -> 'a t) Variant.t -> unit)
    -> unit

  val map :
    'a t
    -> a: (('a -> 'a t)         Variant.t -> 'a                 -> 'r)
    -> b: ((char -> 'a t)       Variant.t -> char               -> 'r)
    -> c: (('a t)               Variant.t                       -> 'r)
    -> d: ((int -> int -> 'a t) Variant.t -> int -> int -> 'a t -> 'r)
    -> 'r

  val to_rank : _ t -> int
  val to_name : _ t -> string

  (** name * number of arguments, ie [("A", 1); ("B", 1); ("C", 0); ("D", 2)]. *)
  val descriptions : (string * int) list
end

Variant.t is defined in Variantslib as follows:

module Variant = struct
  type 'constructor t = {
    name : string;
    (* the position of the constructor in the type definition, starting from 0 *)
    rank : int;
    constructor : 'constructor
  }
end

The fold, iter, and map functions are useful in dealing with the totality of variants. For example, to get a list of all variants when all the constructors are nullary:

type t =
  | First
  | Second
  | Third
  [@@deriving variants]
let all =
  let add acc var = var.Variantslib.Variant.constructor :: acc in
  Variants.fold ~init:[]
    ~first:add
    ~second:add
    ~third:add

Just like with [@@deriving fields], if the type changes, the compiler will complain until this definition is updated as well.

ppx_variant_libs works similarly on simple polymorphic variants (without row variables and without inclusion).

Dependencies (6)

  1. ppxlib >= "0.3.0" & < "0.9.0"
  2. ocaml-migrate-parsetree >= "1.0" & < "2.0.0"
  3. jbuilder >= "1.0+beta18.1"
  4. variantslib >= "v0.11" & < "v0.12"
  5. base >= "v0.11" & < "v0.12"
  6. ocaml >= "4.04.1"

Dev Dependencies

None

Used by (7)

  1. bin_prot = "v0.11.0"
  2. cookies
  3. nacc
  4. pkcs11 >= "0.17.1"
  5. ppx_bap < "v0.14.0"
  6. ppx_expect >= "v0.11.0" & < "v0.12.0"
  7. ppx_jane = "v0.11.0"

Conflicts

None

OCaml

Innovation. Community. Security.