lens v0.3.0 Lens
Summary
Functions
Returns a lens that focuses on all the values in an enumerable
Returns a lens that focuses on the n-th element of a list or tuple
Returns a lens that focuses after the last element of a list. It will always return a nil when accessing, but can be used to append elements
Returns a lens that focuses between a given index and the previous one in a list. It will always return a nil when accessing, but can be used to insert elements
Returns a lens that focuses between a given index and the next one in a list. It will always return a nil when accessing, but can be used to insert elements
Returns a lens that focuses on what both the lenses focus on
Returns a lens that ignores the data and always focuses on the given value
Performs a side effect for each values this lens focuses on in the given data
Returns a lens that does not focus on any part of the data
Returns lens that focuses on all the elements of an enumerable that satisfy the given condition
Returns a lens that focuses before the first element of a list. It will always return a nil when accessing, but can be used to prepend elements
Executes to_list
and returns the first item if the list has only one item otherwise the full list
Returns an updated version of the data and a transformed value from each location the lens focuses on. The
transformation function must return a tuple {value_to_return, value_to_update}
An alias for at
Returns a lens that focuses on all of the supplied indices
Returns a lens that does not change the focus of of the given lens, but puts the results into the given collectable when updating
Returns a lens that focuses on the value under key
Returns a lens that focuses on the value under the given key. If the key does not exist an error will be raised
Returns a lens that focuses on the values of all the keys
Returns a lens that focuses on the values of all the keys. If any of the keys does not exist, an error is raised
Returns an updated version of the data by applying the given function to each value the lens focuses on and building a data structure of the same shape with the updated values in place of the original ones
Select the lens to use based on a matcher function
Returns a lens that focuses on what all of the supplied lenses focus on
Make a lens recursive
Returns a lens that yields the entirety of the data currently under focus
Returns a lens that focuses on a subset of elements focused on by the given lens that satisfy the given condition
Compose a pair of lens by applying the second to the result of the first
Combine the composition of both lens with the first one
Returns a list of values that the lens focuses on in the given data
Types
Functions
Returns a lens that focuses on all the values in an enumerable.
iex> Lens.all |> Lens.get([1, 2, 3])
[1, 2, 3]
Does work with updates but produces a list from any enumerable by default:
iex> Lens.all |> Lens.map(MapSet.new([1, 2, 3]), &(&1 + 1))
[2, 3, 4]
See into on how to rectify this.
Returns a lens that focuses on the n-th element of a list or tuple.
iex> Lens.at(2) |> Lens.get({:a, :b, :c})
:c
iex> Lens.at(1) |> Lens.map([:a, :b, :c], fn :b -> :d end)
[:a, :d, :c]
Returns a lens that focuses after the last element of a list. It will always return a nil when accessing, but can be used to append elements.
iex> Lens.back |> Lens.get([:a, :b, :c])
nil
iex> Lens.back |> Lens.map([:a, :b, :c], fn nil -> :d end)
[:a, :b, :c, :d]
Returns a lens that focuses between a given index and the previous one in a list. It will always return a nil when accessing, but can be used to insert elements.
iex> Lens.before(2) |> Lens.get([:a, :b, :c])
nil
iex> Lens.before(2) |> Lens.map([:a, :b, :c], fn nil -> :d end)
[:a, :b, :d, :c]
Returns a lens that focuses between a given index and the next one in a list. It will always return a nil when accessing, but can be used to insert elements.
iex> Lens.behind(1) |> Lens.get([:a, :b, :c])
nil
iex> Lens.behind(1) |> Lens.map([:a, :b, :c], fn nil -> :d end)
[:a, :b, :d, :c]
Returns a lens that focuses on what both the lenses focus on.
iex> Lens.both(Lens.key(:a), Lens.key(:b) |> Lens.at(1)) |> Lens.get(%{a: 1, b: [2, 3]})
[1, 3]
Bear in mind that what the first lens focuses on will be processed first. Other functions in the library are designed so that the part is processed before the whole and it is advisable to do the same when using this function directly. Not adhering to this principle might lead to the second lens not being able to perform its traversal on a changed version of the structure.
iex> Lens.both(Lens.root, Lens.key(:a)) |> Lens.get_and_map(%{a: 1}, fn x -> {x, :foo} end)
** (FunctionClauseError) no function clause matching in Access.fetch/2
iex> Lens.both(Lens.key(:a), Lens.root) |> Lens.get_and_map(%{a: 1}, fn x -> {x, :foo} end)
{[1, %{a: :foo}], :foo}
Returns a lens that ignores the data and always focuses on the given value.
iex> Lens.const(3) |> Lens.get(:anything)
3
iex> Lens.const(3) |> Lens.map(1, &(&1 + 1))
4
iex> import Integer
iex> lens = Lens.keys([:a, :b]) |> Lens.match(fn v -> if is_odd(v), do: Lens.root, else: Lens.const(0) end)
iex> Lens.map(lens, %{a: 11, b: 12}, &(&1 + 1))
%{a: 12, b: 1}
Performs a side effect for each values this lens focuses on in the given data.
iex> data = %{a: 1, b: 2, c: 3}
iex> fun = fn -> Lens.keys([:a, :c]) |> Lens.each(data, &IO.inspect/1) end
iex> import ExUnit.CaptureIO
iex> capture_io(fun)
"1\n3\n"
Returns a lens that does not focus on any part of the data.
iex> Lens.empty |> Lens.get(:anything)
[]
iex> Lens.empty |> Lens.map(1, &(&1 + 1))
1
Returns lens that focuses on all the elements of an enumerable that satisfy the given condition.
iex> Lens.filter(&Integer.is_odd/1) |> Lens.get([1, 2, 3, 4])
[1, 3]
iex> Lens.filter(&Integer.is_odd/1) |> Lens.map([1, 2, 3, 4], &(&1 + 1))
[2, 2, 4, 4]
Does work with updates but produces a list from any enumerable by default:
iex> Lens.filter(&Integer.is_odd/1) |> Lens.map(MapSet.new([1, 2, 3, 4]), &(&1 + 1))
[2, 2, 4, 4]
See into on how to rectify this.
Returns a lens that focuses before the first element of a list. It will always return a nil when accessing, but can be used to prepend elements.
iex> Lens.front |> Lens.get([:a, :b, :c])
nil
iex> Lens.front |> Lens.map([:a, :b, :c], fn nil -> :d end)
[:d, :a, :b, :c]
Executes to_list
and returns the first item if the list has only one item otherwise the full list.
Returns an updated version of the data and a transformed value from each location the lens focuses on. The
transformation function must return a tuple {value_to_return, value_to_update}
.
iex> data = %{a: 1, b: 2, c: 3}
iex> Lens.keys([:a, :b, :c])
...> |> Lens.satisfy(&Integer.is_odd/1)
...> |> Lens.get_and_map(data, fn v -> {v + 1, v + 10} end)
{[2, 4], %{a: 11, b: 2, c: 13}}
An alias for at
.
Returns a lens that focuses on all of the supplied indices.
iex> Lens.indices([0, 2]) |> Lens.get([:a, :b, :c])
[:a, :c]
iex> Lens.indices([0, 2]) |> Lens.map([1, 2, 3], &(&1 + 1))
[2, 2, 4]
Returns a lens that does not change the focus of of the given lens, but puts the results into the given collectable when updating.
iex> Lens.all |> Lens.into(MapSet.new) |> Lens.map(MapSet.new([-2, -1, 1, 2]), &(&1 * &1))
MapSet.new([1, 4])
Returns a lens that focuses on the value under key
.
iex> Lens.to_list(Lens.key(:foo), %{foo: 1, bar: 2})
[1]
iex> Lens.map(Lens.key(:foo), %{foo: 1, bar: 2}, fn x -> x + 10 end)
%{foo: 11, bar: 2}
If the key doesn’t exist in the map a nil will be returned or passed to the update function.
iex> Lens.to_list(Lens.key(:foo), %{})
[nil]
iex> Lens.map(Lens.key(:foo), %{}, fn nil -> 3 end)
%{foo: 3}
Returns a lens that focuses on the value under the given key. If the key does not exist an error will be raised.
iex> Lens.key!(:a) |> Lens.get(%{a: 1, b: 2})
1
iex> Lens.key!(:a) |> Lens.get([a: 1, b: 2])
1
iex> Lens.key!(:c) |> Lens.get(%{a: 1, b: 2})
** (KeyError) key :c not found in: %{a: 1, b: 2}
Returns a lens that focuses on the values of all the keys.
iex> Lens.keys([:a, :c]) |> Lens.get(%{a: 1, b: 2, c: 3})
[1, 3]
iex> Lens.keys([:a, :c]) |> Lens.map([a: 1, b: 2, c: 3], &(&1 + 1))
[a: 2, b: 2, c: 4]
If any of the keys doesn’t exist the update function will receive a nil.
iex> Lens.keys([:a, :c]) |> Lens.map(%{a: 1, b: 2}, fn nil -> 3; x -> x end)
%{a: 1, b: 2, c: 3}
Returns a lens that focuses on the values of all the keys. If any of the keys does not exist, an error is raised.
iex> Lens.keys!([:a, :c]) |> Lens.get(%{a: 1, b: 2, c: 3})
[1, 3]
iex> Lens.keys!([:a, :c]) |> Lens.map([a: 1, b: 2, c: 3], &(&1 + 1))
[a: 2, b: 2, c: 4]
iex> Lens.keys!([:a, :c]) |> Lens.get(%{a: 1, b: 2})
** (KeyError) key :c not found in: %{a: 1, b: 2}
Returns an updated version of the data by applying the given function to each value the lens focuses on and building a data structure of the same shape with the updated values in place of the original ones.
iex> data = [1, 2, 3, 4]
iex> Lens.filter(&Integer.is_odd/1) |> Lens.map(data, fn v -> v + 10 end)
[11, 2, 13, 4]
Select the lens to use based on a matcher function
iex> selector = fn
...> {:a, _} -> Lens.at(1)
...> {:b, _, _} -> Lens.at(2)
...> end
iex> Lens.match(selector) |> Lens.get({:b, 2, 3})
3
Returns a lens that focuses on what all of the supplied lenses focus on.
iex> Lens.multiple([Lens.key(:a), Lens.key(:b), Lens.root]) |> Lens.get(%{a: 1, b: 2})
[1, 2, %{a: 1, b: 2}]
Make a lens recursive
iex> data = %{
...> items: [
...> %{v: 1, items: []},
...> %{v: 2, items: [
...> %{v: 3, items: []}
...> ]}
...> ]}
iex> lens = Lens.recur(Lens.key(:items) |> Lens.all) |> Lens.key(:v)
iex> Lens.get(lens, data)
[1, 2, 3]
Returns a lens that yields the entirety of the data currently under focus.
iex> Lens.to_list(Lens.root, :data)
[:data]
iex> Lens.map(Lens.root, :data, fn :data -> :other_data end)
:other_data
iex> Lens.key(:a) |> Lens.both(Lens.root, Lens.key(:b)) |> Lens.to_list(%{a: %{b: 1}})
[%{b: 1}, 1]
Returns a lens that focuses on a subset of elements focused on by the given lens that satisfy the given condition.
iex> Lens.keys([:a, :b]) |> Lens.satisfy(&Integer.is_odd/1) |> Lens.get(%{a: 1, b: 2})
1
Compose a pair of lens by applying the second to the result of the first
iex> Lens.seq(Lens.key(:a), Lens.key(:b)) |> Lens.get(%{a: %{b: 3}})
3
Piping lenses has the exact same effect:
iex> Lens.key(:a) |> Lens.key(:b) |> Lens.get(%{a: %{b: 3}})
3
Combine the composition of both lens with the first one.
iex> Lens.seq_both(Lens.key(:a), Lens.key(:b)) |> Lens.get(%{a: %{b: :c}})
[:c, %{b: :c}]
Returns a list of values that the lens focuses on in the given data.
iex> Lens.keys([:a, :c]) |> Lens.to_list(%{a: 1, b: 2, c: 3})
[1, 3]