# `Croma.ListMonad`
[🔗](https://github.com/skirino/croma/blob/main/lib/croma/list_monad.ex#L1)

Implementation of `Croma.Monad` interface for built-in lists.

This empowers the following Haskell-ish syntax for loops using lists:

    iex> use Croma
    ...> Croma.ListMonad.m do
    ...>   i <- [1, 2, 3]
    ...>   j <- [10, 20]
    ...>   pure i + j
    ...> end
    [11, 21, 12, 22, 13, 23]

# `t`

```elixir
@type t(a) :: [a]
```

# `ap`

```elixir
@spec ap(t(a), t((a -&gt; b))) :: t(b) when a: any(), b: any()
```

Default implementation of Applicative's `ap` operation.
Modules that implement `Croma.Monad` may override this default implementation.
Note that the order of arguments is different from the Haskell counterpart, in order to leverage Elixir's pipe operator `|>`.

# `bind`

```elixir
@spec bind(t(a), (a -&gt; t(b))) :: t(b) when a: any(), b: any()
```

Implementation of `bind` operation of Monad.
Alias to `Enum.flat_map/2`.

# `m`
*macro* 

A macro that provides Hakell-like do-notation.

## Examples
    MonadImpl.m do
      x <- mx
      y <- my
      pure f(x, y)
    end

is expanded to

    MonadImpl.bind(mx, fn x ->
      MonadImpl.bind(my, fn y ->
        MonadImpl.pure f(x, y)
      end)
    end)

# `map`

```elixir
@spec map(t(a), (a -&gt; b)) :: t(b) when a: any(), b: any()
```

Default implementation of Functor's `fmap` operation.
Modules that implement `Croma.Monad` may override this default implementation.
Note that the order of arguments is different from the Haskell counterpart, in order to leverage Elixir's pipe operator `|>`.

# `pure`

```elixir
@spec pure(a) :: t(a) when a: any()
```

Implementation of `pure` operation of Monad (or Applicative).
Wraps the given value into a list.

# `sequence`

```elixir
@spec sequence([t(a)]) :: t([a]) when a: any()
```

Converts the given list of monadic (to be precise, applicative) objects into a monadic object that contains a single list.
Modules that implement `Croma.Monad` may override this default implementation.

## Examples (using Croma.Result)
    iex> Croma.Result.sequence([{:ok, 1}, {:ok, 2}, {:ok, 3}])
    {:ok, [1, 2, 3]}

    iex> Croma.Result.sequence([{:ok, 1}, {:error, :foo}, {:ok, 3}])
    {:error, :foo}

---

*Consult [api-reference.md](api-reference.md) for complete listing*
