A lens represents the process of focusing on a specific part of a data structure. We represent this via a view function and an set function, roughly corresponding to object-oriented "getters" and "setters" respectively. Lenses can be composed to access or modify deeply nested structures.

lens(view, set, getter = FALSE)

Arguments

view

A function that takes a data structure of a certain type and returns a subpart of that structure

set

A function that takes a data structure of a certain type and a value and returns a new data structure with the given subpart replaced with the given value. Note that set should not modify the original data.

getter

Default is FALSE, if TRUE the created lens cannot be set into.

Details

Lenses are popular in functional programming because they allow you to build pure, compositional, and re-usable "getters" and "setters".

As noted in the README, using lens directly incurs the following obligations (the "Lens laws"):

  1. Get-Put: If you get (view) some data with a lens, and then modify (set) the data with that value, you get the input data back.

  2. Put-Get: If you put (set) a value into some data with a lens, then get that value with the lens, you get back what you put in.

  3. Put-Put: If you put a value into some data with a lens, and then put another value with the same lens, it's the same as only doing the second put.

"Lenses" which do not satisfy these properties should be documented accordingly. By convention, such objects present in this library are suffixed by "_il" ("illegal lens").

Examples

third_l <- lens(view = function(d) d[[3]], set = function(d, x){ d[[3]] <- x; d }) view(1:10, third_l) # returns 3
#> [1] 3
set(1:10, third_l, 10) # returns c(1:2, 10, 4:10)
#> [1] 1 2 10 4 5 6 7 8 9 10