Witchcraft v1.0.0 Witchcraft.Bifunctor View Source
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
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
Link to this section Functions
bilift(Witchcraft.Bifunctor.t, (... -> any), (... -> any)) :: Witchcraft.Bifunctor.t
The same as bimap/3
, but with the functions curried
Examples
iex> {:ok, 2, "hi"}
...> |> bilift(&*/2, &<>/2)
...> |> bimap(fn f -> f.(9) end, fn g -> g.("?!") end)
{:ok, 18, "hi?!"}
bimap(Witchcraft.Bifunctor.t, (any -> any), (any -> any)) :: Witchcraft.Bifunctor.t
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
┌------------------------------------┐
↓ |
%Combo{a: 50, b: :ok, c: "hello"} |> bimap(&(&1 * 100), &String.upcase/1)
↑ |
└---------------------------------┘
#=> %Combo{a: 500, b: :ok, c: "HELLO"}
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"}
lift_first(Witchcraft.Bifunctor.t, (... -> any)) :: Witchcraft.Bifunctor.t
The same as map_first
, but with a curried function
Examples
iex> {:ok, 2, "hi"}
...> |> lift_first(&*/2)
...> |> map_first(fn f -> f.(9) end)
{:ok, 18, "hi"}
lift_second(Witchcraft.Bifunctor.t, (... -> any)) :: Witchcraft.Bifunctor.t
The same as map_second
, but with a curried function
Examples
iex> {:ok, 2, "hi"}
...> |> lift_second(&<>/2)
...> |> map_second(fn f -> f.("?!") end)
{:ok, 2, "hi?!"}
map_first(Witchcraft.Bifunctor.t, (any -> any)) :: Witchcraft.Bifunctor.t
map
a function over the first value only
Examples
iex> {:ok, 2, "hi"} |> map_first(&(&1 * 100))
{:ok, 200, "hi"}
map_second(Witchcraft.Bifunctor.t, (any -> any)) :: Witchcraft.Bifunctor.t
map
a function over the second value only
Examples
iex> {:ok, 2, "hi"} |> map_second(&(&1 <> "!?"))
{:ok, 2, "hi!?"}