View Source Witchcraft.Bifunctor (Witchcraft v1.0.6-doma)
Similar to Witchcraft.Functor
, but able to map two functions over two
separate portions of some data structure (some product type).
Especially helpful when you need different hebaviours on different fields.
type-class
Type Class
An instance of Witchcraft.Bifunctor
must also implement Witchcraft.Functor
,
and define Witchcraft.Apply.ap/2
.
Functor [map/2]
↓
Bifunctor [bimap/2]
Link to this section Summary
Functions
The same as bimap/3
, but with the functions curried
map
separate fuctions over two fields in a product type.
The same as map_first
, but with a curried function
The same as map_second
, but with a curried function
map
a function over the first value only
map
a function over the second value only
Link to this section Types
@type t() :: any()
Link to this section Functions
The same as bimap/3
, but with the functions curried
examples
Examples
iex> {:ok, 2, "hi"}
...> |> bilift(&*/2, &<>/2)
...> |> bimap(fn f -> f.(9) end, fn g -> g.("?!") end)
{:ok, 18, "hi?!"}
map
separate fuctions over two fields in a product type.
The order of fields doesn't always matter in the map. The first/second function application is determined by the instance. It also does not have to map all fields in a product type.
diagram
Diagram
┌------------------------------------┐
↓ |
%Combo{a: 5, b: :ok, c: "hello"} |> bimap(&(&1 * 100), &String.upcase/1)
↑ |
└---------------------------------┘
#=> %Combo{a: 500, b: :ok, c: "HELLO"}
examples
Examples
iex> {1, "a"} |> bimap(&(&1 * 100), &(&1 <> "!"))
{100, "a!"}
iex> {:msg, 42, "number is below 50"}
...> |> bimap(&(%{subject: &1}), &String.upcase/1)
{:msg, %{subject: 42}, "NUMBER IS BELOW 50"}
The same as map_first
, but with a curried function
examples
Examples
iex> {:ok, 2, "hi"}
...> |> lift_first(&*/2)
...> |> map_first(fn f -> f.(9) end)
{:ok, 18, "hi"}
The same as map_second
, but with a curried function
examples
Examples
iex> {:ok, 2, "hi"}
...> |> lift_second(&<>/2)
...> |> map_second(fn f -> f.("?!") end)
{:ok, 2, "hi?!"}
map
a function over the first value only
examples
Examples
iex> {:ok, 2, "hi"} |> map_first(&(&1 * 100))
{:ok, 200, "hi"}
map
a function over the second value only
examples
Examples
iex> {:ok, 2, "hi"} |> map_second(&(&1 <> "!?"))
{:ok, 2, "hi!?"}