Lenses are a functional programming abstraction that provides a way to focus on a specific part of a data structure and perform operations on it. In Phunkie, lenses offer a composable way to view and modify nested data structures.
A lens consists of two functions:
class Lens {
public function get($a); // Gets the focused value
public function set($b, $a); // Sets a new value
public function mod($f, $a); // Modifies the focused value using a function
}
Retrieves the focused value:
$userNameLens = new Lens(
fn(User $user) => $user->getName(),
fn(Name $name, User $user) => $user->copy(["name" => $name])
);
$name = $userNameLens->get($user); // Gets user's name
Updates the focused value:
$newUser = $userNameLens->set(new Name("Chuck Norris"), $user);
Modifies the focused value using a function:
$upperCaseName = $userNameLens->mod(
fn(Name $name) => new Name(strtoupper($name->getName())),
$user
);
Lenses can be composed to focus on deeply nested structures:
$lenses = makeLenses("address", "country", "code");
$codeLens = combine($lenses->address, $lenses->country, $lenses->code);
$countryCode = $codeLens->get($user); // Gets nested country code
Lenses must satisfy three fundamental laws:
$lens->set($lens->get($a), $a) === $a
$lens->get($lens->set($b, $a)) === $b
$lens->set($c, $lens->set($b, $a)) === $lens->set($c, $a)
Phunkie provides several built-in lens constructors:
trivial()
: A lens that focuses on nothingself()
: A lens that focuses on the whole structurefst()
: A lens that focuses on the first element of a Pairsnd()
: A lens that focuses on the second element of a Paircontains()
: A lens for checking/updating Set membershipmember()
: A lens for accessing/modifying Map valuesmakeLenses()
: Creates lenses for object properties or array keys$lenses = makeLenses("name");
$userName = $lenses->name->get($user);
$lenses = makeLenses("address", "street");
$streetLens = combine($lenses->address, $lenses->street);
$mapLens = member("key");
$value = $mapLens->get($immMap);
makeLenses()
for common property access