focus v0.1.0 Focus.Lens
Experimenting with functional lenses.
Summary
Functions
Given a list of lenses and a structure, apply Lens.view for each lens to the structure
Compose with most general lens on the left
Define a lens to focus on a part of a data structure
Modify the part of a data structure that a lens focuses on
Update the part of a data structure the lens focuses on
Get a piece of a data structure that a lens focuses on; returns {:ok, data} | {:error, :bad_lens_path}
Get a piece of a data structure that a lens focuses on
Infix lens composition
Types
Functions
Given a list of lenses and a structure, apply Lens.view for each lens to the structure.
Examples
iex> homer = %{name: "Homer", job: "Nuclear Safety Inspector", children: ["Bart", "Lisa", "Maggie"]}
iex> lenses = [Focus.Lens.makeLens(:name), Focus.Lens.makeLens(:children)]
iex> Focus.Lens.apply_list(lenses, homer)
["Homer", ["Bart", "Lisa", "Maggie"]]
Compose with most general lens on the left
Examples
iex> alias Focus.Lens
iex> marge = %{name: "Marge", address: %{street: "123 Fake St.", city: "Springfield"}}
iex> addressLens = Lens.makeLens(:address)
iex> streetLens = Lens.makeLens(:street)
iex> composed = Lens.compose(addressLens, streetLens)
iex> Lens.view(composed, marge)
{:ok, "123 Fake St."}
Define a lens to focus on a part of a data structure.
Examples
iex> alias Focus.Lens
iex> person = %{name: "Homer"}
iex> nameLens = Lens.makeLens(:name)
iex> nameLens.getter.(person)
"Homer"
iex> nameLens.setter.(person).("Bart")
%{name: "Bart"}
Modify the part of a data structure that a lens focuses on.
Examples
iex> alias Focus.Lens
iex> marge = %{name: "Marge", address: %{street: "123 Fake St.", city: "Springfield"}}
iex> nameLens = Lens.makeLens(:name)
iex> Lens.over(nameLens, marge, &String.upcase/1)
%{name: "MARGE", address: %{street: "123 Fake St.", city: "Springfield"}}
Update the part of a data structure the lens focuses on.
Examples
iex> alias Focus.Lens
iex> marge = %{name: "Marge", address: %{street: "123 Fake St.", city: "Springfield"}}
iex> nameLens = Lens.makeLens(:name)
iex> Lens.set(nameLens, marge, "Homer")
%{name: "Homer", address: %{street: "123 Fake St.", city: "Springfield"}}
iex> alias Focus.Lens
iex> marge = %{name: "Marge", address: %{street: "123 Fake St.", city: "Springfield"}}
iex> addressLens = Lens.makeLens(:address)
iex> streetLens = Lens.makeLens(:street)
iex> composed = Lens.compose(addressLens, streetLens)
iex> Lens.set(composed, marge, "42 Wallaby Way")
%{name: "Marge", address: %{street: "42 Wallaby Way", city: "Springfield"}}
Get a piece of a data structure that a lens focuses on; returns {:ok, data} | {:error, :bad_lens_path}
Examples
iex> alias Focus.Lens
iex> marge = %{name: "Marge", address: %{street: "123 Fake St.", city: "Springfield"}}
iex> nameLens = Lens.makeLens(:name)
iex> Lens.view(nameLens, marge)
{:ok, "Marge"}
Get a piece of a data structure that a lens focuses on.
Examples
iex> alias Focus.Lens
iex> marge = %{name: "Marge", address: %{street: "123 Fake St.", city: "Springfield"}}
iex> nameLens = Lens.makeLens(:name)
iex> Lens.view!(nameLens, marge)
"Marge"
Infix lens composition
Examples
iex> import Focus.Lens
iex> alias Focus.Lens
iex> marge = %{name: "Marge", address: %{
...> local: %{number: 123, street: "Fake St."},
...> city: "Springfield"}
...> }
iex> addressLens = Lens.makeLens(:address)
iex> localLens = Lens.makeLens(:local)
iex> streetLens = Lens.makeLens(:street)
iex> addressLens ~> localLens ~> streetLens |> Lens.view!(marge)
"Fake St."