Toda Monad é um tipo genérico. Para um tipo genérico ser uma monad, ele tem que suportar a seguinte "interface":
Dado que nossa monad é o tipo M onde A é algum tipo de parâmetro, devem existir as seguintes funçÕes:
function pure(A): M<A>
function bind<B>(M<A>, A -> M<B>): M<B>
A função pure "injeta" um valor dentro da monad com contexto "neutro". Por exemplo se o argumento de pure for x, na monad Option, ela retorna Some(x). Na monad Promise, ela retorna uma Promise que resolve imediatamente com o valor passado (em JS essa função se chama Promise.resolve(valor))
A função bind permite pegar um valor "com contexto" e aplicar uma função a ele "fora" do contexto - desde que retornemos o mesmo contexto. Em JS, essa função é o .then(callback) (o receptor do método faz o papel de primeiro argumento). Em Rust, vários tipos a expõem e chamam ela de .and_then, usada da seguinte forma:
op1()
.and_then(op2)
.and_then(op3)
Se as funções op1, op2 e op3 todas retornam um Option, isso encapsula a lógica "falhar quando qualquer função falhar", pois os callbacks não serão chamados em valores None, ao invés disso retornando-os diretamente.