package ppx_variants_conv
Install
Dune Dependency
Authors
Maintainers
Sources
sha256=7e34bb52e309c42fa8a8517c43343f5ce8f514f80806fcfc7e9b360e6fc69820
md5=75e957c4fd6efbf2f4a6de08f2729729
README.md.html
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 make_matcher :
a:(('a -> 'a t) Variant.t -> 'b -> ('c -> 'd) * 'e)
-> b:((char -> 'f t) Variant.t -> 'e -> (char -> 'd) * 'g)
-> c:('h t Variant.t -> 'g -> (unit -> 'd) * 'i)
-> d:((int -> int -> 'j t) Variant.t -> 'i -> (int -> int -> 'd) * 'k)
-> 'b
-> ('c t -> 'd) * 'k
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).