package ppx_accessor
[@@deriving] plugin to generate accessors for use with the Accessor libraries
Install
Dune Dependency
Authors
Maintainers
Sources
v0.14.1.tar.gz
sha256=c1ed1fd7b217a87fe311a918e73ed7d7bcd3c94bcd4ad607f1d5b145309ed4b1
md5=3c96720de723f37be96666e875813c02
README.org.html
README.org
This extension provides two features: - Generate ~Accessor~ isomorphisms, fields, variants, and optionals from types. - Eta expand ~Accessor~-defining expressions to avoid the value restriction. * Syntax - Type definitions :: ~[@@deriving accessors]~ - Expressions :: ~[%accessor EXPR]~ * Usage ** Polymorphizing accessors Wrap an expression defining an accessor like this: #+BEGIN_SRC ocaml [%accessor Accessor.field ~get ~set] #+END_SRC This causes the expression to be as polymorphic as possible via eta expansion. The generated code in the above example would be something like this: #+BEGIN_SRC ocaml { Accessor.f = (fun selector mapping -> (Accessor.field ~get ~set).f selector mapping) } #+END_SRC ** Deriving accessors Annotate a type definition like this: #+BEGIN_SRC ocaml type t = { foo : int ; bar : string } [@@deriving accessors] #+END_SRC This generates different accessors depending on the type definition. You can optionally specify to generate the accessors in a submodule, like this: #+BEGIN_SRC ocaml type t = { foo : int ; bar : string } [@@deriving accessors ~submodule:My_submodule] #+END_SRC This can be useful to avoid name clashes with ~[@@deriving fields]~. If you want to derive both ~accessors~ and ~fields~, you have three options, but only two are useful: - Derive accessors before fields :: ~[@@deriving accessors, fields]~ The getter functions generated by ~fields~ will shadow the accessors, so there is little point in this arrangement. - Derive fields before accessors :: ~[@@deriving fields, accessors]~ The accessors will shadow the getter functions generated by ~fields~, but you still get the ~Fields~ module. - Provide a submodule for accessors values :: ~[@@deriving accessors ~submodule:Some_submodule, fields]~ Nothing will be shadowed, but the accessors will be stuffed into a submodule, which makes using them more verbose. *** Records =ppx_accessor= generates one accessor per record field. **** Multiple fields Records with multiple fields result in ~field~ accessors. #+BEGIN_SRC ocaml type t = { foo : int ; bar : string } [@@deriving accessors] #+END_SRC For the above type, these accessors would be generated: #+BEGIN_SRC ocaml let foo = [%accessor Accessor.field ~get:(fun t -> t.foo) ~set:(fun t foo -> { t with foo }) let bar = [%accessor Accessor.field ~get:(fun t -> t.bar) ~set:(fun t bar -> { t with bar }) #+END_SRC **** One field Records with one field result in an ~isomorphism~ accessor. #+BEGIN_SRC ocaml type t = { foo : int } [@@deriving accessors] #+END_SRC For the above type, this accessor would be generated: #+BEGIN_SRC ocaml let foo = [%accessor Accessor.isomorphism ~get:(fun t -> t.foo) ~construct:(fun foo -> { foo }) #+END_SRC *** Variants =ppx_accessor= generates one accessor per constructor that doesn't use inline record syntax. Inline records result in a submodule named after the constructor which contains one accessor per field of the inline record. **** Multiple constructors Variants with multiple constructors result in ~variant~ and ~optional~ accessors. #+BEGIN_SRC ocaml type t = | Foo | Bar of int * string | Baz of { a : float } | Quux of { a : int; b : string } [@@deriving accessors] #+END_SRC For the above type, these accessors would be generated: #+BEGIN_SRC ocaml let foo = [%accessor Accessor.variant ~match_:(function | Foo -> First () | (Bar _ | Baz _ | Quux _) as r -> Second r) ~construct:(fun () -> Foo)] let bar = [%accessor Accessor.variant ~match_:(function | Bar (x, y) -> First (x, y) | (Foo | Baz _ | Quux _) as r -> Second r) ~construct:(fun (x, y) -> Bar (x, y)] module Baz = struct let a = [%accessor Accessor.variant ~match_:(function | Baz t -> First t.a | (Foo | Bar _ | Quux _) as r -> Second r) ~construct:(fun a -> Baz { a })] end module Quux = struct let a = [%accessor Accessor.optional ~match_:(function | Quux t -> First t.a | (Foo | Bar _ | Baz _) as r -> Second r) ~set:(fun t a -> match t with | Quux t -> Quux { t with a } | (Foo | Bar _ | Baz _) as r -> r)] let b = [%accessor Accessor.optional ~match_:(function | Quux t -> First t.b | (Foo | Bar _ | Baz _) as r -> Second r) ~set:(fun t b -> match t with | Quux t -> Quux { t with b } | (Foo | Bar _ | Baz _) as r -> r)] end #+END_SRC **** Single constructors Variants with one constructor result in either an ~isomorphism~ or ~field~ accessor. ***** Constructors without inline record syntax A singleton variant that does not use inline record syntax results in an isomorphism. #+BEGIN_SRC ocaml type t = Foo of int [@@deriving accessors] #+END_SRC For the above type, this accessor would be generated: #+BEGIN_SRC ocaml let foo = [%accessor Accessor.isomorphism ~get:(fun (Foo n) -> n) ~construct:(fun n -> Foo n)] #+END_SRC ***** Constructors with inline record syntax A singleton variant using inline record syntax is treated like a normal record, but the accessors live in a submodule named after the constructor. ****** Multiple fields Records with multiple fields result in ~field~ accessors. #+BEGIN_SRC ocaml type t = Foo of { foo : int ; bar : string } [@@deriving accessors] #+END_SRC For the above type, these accessors would be generated: #+BEGIN_SRC ocaml module Foo = struct let foo = [%accessor Accessor.field ~get:(fun (Foo t) -> t.foo) ~set:(fun (Foo t) foo -> Foo { t with foo }) let bar = [%accessor Accessor.field ~get:(fun (Foo t) -> t.bar) ~set:(fun (Foo t) bar -> Foo { t with bar }) end #+END_SRC ****** One field Records with one field result in an ~isomorphism~ accessor. #+BEGIN_SRC ocaml type t = A of { foo : int } [@@deriving accessors] #+END_SRC For the above type, this accessor would be generated: #+BEGIN_SRC ocaml module A = struct let foo = [%accessor Accessor.isomorphism ~get:(fun (A t) -> t.foo) ~construct:(fun foo -> A { foo }) end #+END_SRC *** Polymorphic variants =ppx_accessor= generates one ~variant~ accessor per constructor in a polymorphic variant. If there is only one constructor, it generates an ~isomorphism~ instead. If the type definition inherits from another polymorphic variant, it generates a ~variant~ accessor for converting to and from the inherited type.
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>