{"id":13726202,"url":"https://github.com/janestreet/ppx_enumerate","last_synced_at":"2025-05-03T03:30:52.685Z","repository":{"id":147427737,"uuid":"43162537","full_name":"janestreet/ppx_enumerate","owner":"janestreet","description":"Generate a list containing all values of a finite type","archived":false,"fork":false,"pushed_at":"2025-04-28T18:35:16.000Z","size":128,"stargazers_count":26,"open_issues_count":1,"forks_count":4,"subscribers_count":8,"default_branch":"master","last_synced_at":"2025-04-28T19:38:25.245Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"OCaml","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/janestreet.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGES.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2015-09-25T17:02:51.000Z","updated_at":"2025-04-28T18:35:19.000Z","dependencies_parsed_at":"2024-01-06T02:03:20.734Z","dependency_job_id":"e0be8471-90ca-463c-a030-d96381235b39","html_url":"https://github.com/janestreet/ppx_enumerate","commit_stats":null,"previous_names":[],"tags_count":16,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/janestreet%2Fppx_enumerate","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/janestreet%2Fppx_enumerate/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/janestreet%2Fppx_enumerate/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/janestreet%2Fppx_enumerate/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/janestreet","download_url":"https://codeload.github.com/janestreet/ppx_enumerate/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252137512,"owners_count":21700227,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-03T01:02:55.586Z","updated_at":"2025-05-03T03:30:52.678Z","avatar_url":"https://github.com/janestreet.png","language":"OCaml","funding_links":[],"categories":["OCaml"],"sub_categories":[],"readme":"ppx_enumerate\n=============\n\nGenerate a list containing all values of a finite type.\n\n`ppx_enumerate` is a ppx rewriter which generates a definition for the\nlist of all values of a type with (for a type which only has finitely\nmany values).\n\nBasic Usage\n-----------\n\nThe basic usage is simply to add \"[@@deriving enumerate]\" after the type\ndefinition.  For example:\n\n```ocaml\ntype t =\n  | Foo\n  | Bar of bool\n  | Baz of [`A | `B of unit option]\n  [@@deriving enumerate]\n```\n\nwill produce a value `val all : t list`, whose value is equal to\n\n```ocaml\n[ Foo; Bar true; Bar false; Baz `A; Baz (`B None); Baz (`B Some ()) ]\n```\n\nin some order (that is, there is no guarantee about the order of the list).\n\nPolymorphic types\n-----------------\n\nIn a similar fashion as sexplib, using '[@@deriving enumerate]' on polymorphic\ntypes produces a function for [all].  For example,\n\n```ocaml\ntype 'a t =\n  | Foo\n  | Bar of 'a option\n  [@@deriving enumerate]\n```\n\nwill produce a value `val all : 'a list -\u003e 'a t list`, whose value is\nsemantically equal to\n\n```ocaml\nfun all_of_a -\u003e Foo :: Bar None :: List.map all_of_a ~f:(fun x -\u003e Bar (Some x))\n```\n\nTypes not named `t`\n-------------------\n\nIf the type is not named `t`, then the enumeration is called\n`all_of_\u003ctype_name\u003e` instead of `all`.\n\nRecords and Tuples\n------------------\n\nProduct types are supported as well as sum types.  For example,\n\n```ocaml\ntype t =\n  { foo : [`A | `B]\n  ; bar : [`C | `D]\n  } [@@deriving enumerate]\n```\n\nproduces a `val all : t list` whose value is equal (up to order) to:\n\n```ocaml\n[ { foo = `A; bar = `C }; { foo = `A; bar = `D };\n  { foo = `B; bar = `C }; { foo = `B; bar = `D };\n]\n```\n\nTuples and variants with multiple arguments are similarly supported.\n\nOverriding the `all` value\n---------------------------\n\nJust like with sexplib, it can sometimes be useful to provide a custom\nvalue of `all`.  For example, you might define a type of bounded\nintegers:\n\n```ocaml\nmodule Small_int : sig\n  type t = private int [@@deriving enumerate]\n  val create_exn : int -\u003e t\nend = struct\n  type t = int\n  let limit = 100\n  let create_exn i = if i \u003c 0 || i \u003e= limit then failwith \"out of bounds\"; i\n  let all = List.init limit ~f:(fun i -\u003e i)\nend\n```\n\nYou could then use `Small_int.t` as normal with other types using\n`[@@deriving enumerate]`:\n\n```ocaml\ntype t =\n  | Foo\n  | Bar of Small_int.t option\n  [@@deriving enumerate]\n```\n\nCustom attribute\n----------------\n\nYou can also override `all` for a type within a type definition using the\n`[@enumerate.custom]` attribute:\n\n```ocaml\ntype t =\n  | Foo\n  | Bar of (string[@enumerate.custom [ \"baz\"; \"qux\" ]]) * bool\n```\n\nThis can be useful in cases where you want to use `enumerate` to help exercise different\ncodepaths based on which case you're in, but the contents are not enumerable. For example,\nyour code may have different control flow based on whether a `string option` is `Some str`\nor `None`, but not have material changes based on the value of `str`, in which case you\ncould use `(string [@enumerate.custom [ \"example\" ]]) option`.\n\nUsing `all` without defining a type name\n----------------------------------------\n\nYou don't have to define a type name to be able to create the list of\nvalues of a type. You do it for any type expression by using the `all`\nquotation. For example:\n\n```ocaml\n[%all: bool * bool]\n```\n\nwhich will evaluate to:\n\n```ocaml\n[ (true, true); (true, false); (false, false); (false, true) ]\n```\n\nKnown issues\n------------\n\nUsing `all` for polymorphic variants with duplicated constructors leads\nto duplicate values in the resulting lists:\n\n```ocaml\ntype t = [ `A ] [@@deriving enumerate]\nlet () = assert ([%all: [ t | t ] ] = [ `A; `A ])\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjanestreet%2Fppx_enumerate","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjanestreet%2Fppx_enumerate","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjanestreet%2Fppx_enumerate/lists"}