Packages

Category theory concepts in gleam.

Retired package: Renamed - cat

Current section

Files

Jump to
category_theory src category_theory@monoid.erl
Raw

src/category_theory@monoid.erl

-module(category_theory@monoid).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-export([mconcat/2, unit_monoid/0, list_monoid/0, option_monoid/1, tuple_monoid/2, triple_monoid/3, function_monoid/1]).
-export_type([monoid/1]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
?MODULEDOC(
" The Monoid module contains the `Monoid` type with who's minimal implementations are `mempty` and `mappend`. \\\n"
" We also define the `mconcat` function in terms of mempty and mappend. \\\n"
" Finally, this module contains several instances for the monoid type.\n"
).
-type monoid(FMZ) :: {monoid, FMZ, fun((FMZ, FMZ) -> FMZ)}.
-file("src/category_theory/monoid.gleam", 35).
?DOC(" Fold a `list of monoids` using mappend.\n").
-spec mconcat(monoid(FNA), list(FNA)) -> FNA.
mconcat(Mono, Monoid_list) ->
_pipe = Monoid_list,
gleam@list:fold(_pipe, erlang:element(2, Mono), erlang:element(3, Mono)).
-file("src/category_theory/monoid.gleam", 48).
?DOC(
" Returns the `canonical implementation` of the `monoid type for Nil` (unit type).\n"
" ### Examples\n"
" ```gleam\n"
" mono_unit.mappend(mono_unit.mempty, Nil)\n"
" // -> Nil\n"
" ```\n"
).
-spec unit_monoid() -> monoid(nil).
unit_monoid() ->
{monoid, nil, fun(_, _) -> nil end}.
-file("src/category_theory/monoid.gleam", 61).
?DOC(
" Returns the `canonical implementation` of the `monoid type for List`.\n"
" ### Examples\n"
" ```gleam\n"
" [1, 2]\n"
" |> mono_list.mappend([3, 4, 5])\n"
" |> mono_list.mappend(mono_list.mempty)\n"
" |> mono_list.mappend([6])\n"
" // -> [1, 2, 3, 4, 5, 6]\n"
" ```\n"
).
-spec list_monoid() -> monoid(list(any())).
list_monoid() ->
{monoid, [], fun lists:append/2}.
-file("src/category_theory/monoid.gleam", 78).
?DOC(
" Returns the `canonical implementation` of the `monoid type for Option(a)`. \\\n"
" We must have a Monoid(a) type instance.\n"
" ### Examples\n"
" ```gleam\n"
" let mono_string = Monoid(mempty: \"\", mappend: fn(x: String, y: String) -> String { x <> y })\n"
" let mono_maybe = option_monoid(mono_string)\n"
" \n"
" Some(\"ab\")\n"
" |> mono_maybe.mappend(Some(\"cd\"))\n"
" // -> Some(\"abcd\")\n"
" mono_maybe.mappend(Some(\"abc\"), maybe.mempty)\n"
" // -> None\n"
" ```\n"
).
-spec option_monoid(monoid(FNF)) -> monoid(gleam@option:option(FNF)).
option_monoid(Mono_a) ->
{monoid, none, fun(M1, M2) -> case {M1, M2} of
{none, _} ->
none;
{_, none} ->
none;
{{some, A1}, {some, A2}} ->
{some, (erlang:element(3, Mono_a))(A1, A2)}
end end}.
-file("src/category_theory/monoid.gleam", 90).
?DOC(
" Returns the `canonical implementation` of the `monoid type for Tuple`. \\\n"
" We must have a Monoid(a) and a Monoid(b) type instance.\n"
).
-spec tuple_monoid(monoid(FNJ), monoid(FNL)) -> monoid({FNJ, FNL}).
tuple_monoid(Mono_a, Mono_b) ->
{monoid,
{erlang:element(2, Mono_a), erlang:element(2, Mono_b)},
fun(M1, M2) ->
{(erlang:element(3, Mono_a))(
erlang:element(1, M1),
erlang:element(1, M2)
),
(erlang:element(3, Mono_b))(
erlang:element(2, M1),
erlang:element(2, M2)
)}
end}.
-file("src/category_theory/monoid.gleam", 101).
?DOC(
" Returns the `canonical implementation` of the `monoid type for Triple`. \\\n"
" We must have a Monoid type instance for a, b, and c.\n"
).
-spec triple_monoid(monoid(FNO), monoid(FNQ), monoid(FNS)) -> monoid({FNO,
FNQ,
FNS}).
triple_monoid(Mono_a, Mono_b, Mono_c) ->
{monoid,
{erlang:element(2, Mono_a),
erlang:element(2, Mono_b),
erlang:element(2, Mono_c)},
fun(M1, M2) ->
{(erlang:element(3, Mono_a))(
erlang:element(1, M1),
erlang:element(1, M2)
),
(erlang:element(3, Mono_b))(
erlang:element(2, M1),
erlang:element(2, M2)
),
(erlang:element(3, Mono_c))(
erlang:element(3, M1),
erlang:element(3, M2)
)}
end}.
-file("src/category_theory/monoid.gleam", 119).
?DOC(" Monoid instance for functions where the `result type` must be a Monoid instance.\n").
-spec function_monoid(monoid(FNV)) -> monoid(fun((any()) -> FNV)).
function_monoid(Mono_b) ->
{monoid,
fun(_) -> erlang:element(2, Mono_b) end,
fun(F, G) -> fun(X) -> (erlang:element(3, Mono_b))(F(X), G(X)) end end}.