-type monad() :: module() | {module(), monad()}.
-type monadic(_M, _A) :: any().
-callback mplus(monadic(M, A), monadic(M, A)) -> monadic(M, A).
-callback mzero() -> monadic(_M, _A).
-spec guard(M, boolean()) -> monadic(M, ok).
-spec mfilter(M, fun((A) -> boolean()), monadic(M, A)) -> monadic(M, A).
-spec msum(M, [monadic(M, A)]) -> monadic(M, A).