FunLand.Monad (fun_land v0.10.0)
A Monad: a sequence of operations inside a context.
Monads are hard to explain, because they are very powerful but extremely general at the same time.
Simply put: To be a Monad, something has to be Applicative, as well as Chainable (and therefore also be Appliable and Mappable). Therefore, a monad is very versatile, as it allows us to perform all these four operations:
new
, which allows us to put anything inside a new structure of this kind.map
, which allows us to take a normal function transforming one element, and change it into a function that transforms all of the contents of the structure.chain
, which allows us to take a function that usually returns a new structure of this kind, and instead apply it on an already-existing structure, the result being a single new structure instead of multiple layers of it.apply_with
, which allows us to take a partially-applied function inside a structure of this kind to be applied with another structure of this kind.
This allows us to:
- Take any normal value and put it into our new structure.
- Use any normal functions as well as any functions returning a structure of this kind to be used in a sequence of operations.
- determine what should happen between subsequent operations. (when/how/if the next step should be executed)
Link to this section Summary
Functions
Allows you to write multiple consecutive operations using this monad on new lines. This is called 'monadic do-notation'.
Link to this section Functions
apply_with(a, b)
chain(a, fun)
map(a, fun)
Allows you to write multiple consecutive operations using this monad on new lines. This is called 'monadic do-notation'.
Rules:
- Every normal line returns a new instance of the monad.
- You can write
x <- some_expr_returning_a_monad_instance
to bindx
to whatever is inside the monad. You can then usex
on any subsequent lines. - If you want to use one or multiple statements, use
let something = some_statement
orlet something = do ...
The final line is of course expected to also return an instance of the monad.
Use new
at any time to new a value back into a monad if you need.
Inside the monadic context, the module of the monad that was defined is automatically imported.
Any local calls to e.g. new
, apply
, chain
or functions you've defined yourself in your monad module will thus be called on your module.
Examples
iex> require FunLand.Monad
iex> FunLand.Monad.monadic({:ok, nil}) do
iex> x <- {:ok, 10}
iex> y <- {:ok, 20}
iex> new(x * y)
iex> end
{:ok, 200}
iex> require FunLand.Monad
iex> FunLand.Monad.monadic({:ok, nil}) do
iex> x <- {:ok, 10}
iex> y <- {:error, :something_went_wrong}
iex> new(x * y)
iex> end
{:error, :something_went_wrong}