Playing with Functors
Setup
Mix.install([
{:witchcraft, "~> 1.0"},
{:algae, "~> 1.2"}
])
use Witchcraft
alias Algae.Either.{Right, Left}
graph TD
Functor -.-> Traversable
Functor -.-> Apply
Functor -.-> Bitfunctor
Apply -.-> Applicative
Apply -.-> Chain
Applicative -.-> Monad
Chain -.-> Monad
Functor
%Right{right: 100}
~> fn y -> y * 2 end
%Right{right: [100, 200, 300]}
~> (&List.first/1)
%Right{right: [100, 200, 300]}
|> map(&List.first/1)
%Right{right: [100, 200, 300]}
|> map(&Enum.map(&1, fn x -> x + 1 end))
Apply
%Right{right: 10} ~>> %Right{right: fn x -> x * 2 end}
%Right{right: 10} |> convey(%Right{right: fn x -> x * 2 end})
lift vs map
%Right{right: 1000}
|> lift(fn x, y, z -> x + y + z end)
~> fn x -> x.(1) end
~> fn x -> x.(1) end
[10, 20, 30]
|> lift(fn x, y, z -> x + y + z end)
|> Enum.map(fn x -> x.(1) end)
|> Enum.map(fn x -> x.(1) end)
%Right{right: 1000}
|> map(fn x, y -> x + y end)
Traverse
%Right{right: [100, 200, 300]}
|> traverse(fn x -> [x] end)
%Right{right: [100, 200, 300]}
|> traverse(fn x -> x end)
|> map(fn x ->
x ~> fn y -> y + 1 end
end)
[%Right{right: 100}, %Right{right: 200}, %Right{right: 300}]
|> traverse(fn x -> x end)
~> (&List.first/1)
[%Right{right: 100}, %Right{right: 200}, %Right{right: 300}]
|> traverse(fn x -> x end) >>>
fn x -> Enum.map(x, fn x -> x * 2 end) end