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

t()
t() :: %Focus.Lens{getter: (any -> any), setter: ((any -> any) -> any)}
traversable()
traversable() :: map | list | tuple

Functions

apply_list(lenses, structure)
apply_list([Focus.Lens.t], traversable) :: [any]

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(lens1, lens2)

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."}
makeLens(path)
makeLens(list) :: Focus.Lens.t

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"}
over(lens, structure, f)
over(Focus.Lens.t, traversable, (any -> any)) :: traversable

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"}}
set(lens, structure, val)

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"}}
view(lens, structure)
view(Focus.Lens.t, traversable) ::
  {:error, :bad_arg} |
  {:ok, any}

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"}
view!(lens, structure)
view!(Focus.Lens.t, traversable) :: any | nil

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"
x ~> y

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."