Skip to content

Instantly share code, notes, and snippets.

@coproduto
Last active June 6, 2024 13:06
Show Gist options
  • Save coproduto/a3aed8656b1e757ccfa159dd648a3c82 to your computer and use it in GitHub Desktop.
Save coproduto/a3aed8656b1e757ccfa159dd648a3c82 to your computer and use it in GitHub Desktop.

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment