Atualmente, fala-se muito em mônadas. Eu li alguns artigos / postagens de blog, mas não posso ir longe o suficiente com seus exemplos para entender completamente o conceito. O motivo é que as mônadas são um conceito de linguagem funcional e, portanto, os exemplos estão em idiomas com os quais não trabalhei (já que não usei uma linguagem funcional em profundidade). Não consigo entender a sintaxe profundamente o suficiente para seguir os artigos completamente ... mas posso dizer que há algo que vale a pena entender por lá.
No entanto, eu conheço C # muito bem, incluindo expressões lambda e outros recursos funcionais. Eu sei que o C # tem apenas um subconjunto de recursos funcionais e, portanto, talvez as mônadas não possam ser expressas em C #.
No entanto, certamente é possível transmitir o conceito? Pelo menos eu espero que sim. Talvez você possa apresentar um exemplo de C # como base e depois descrever o que um desenvolvedor de C # gostaria que ele pudesse fazer a partir daí, mas não pode, porque a linguagem carece de recursos de programação funcional. Isso seria fantástico, porque transmitiria a intenção e os benefícios das mônadas. Então, aqui está a minha pergunta: Qual é a melhor explicação que você pode dar sobre mônadas para um desenvolvedor de C # 3?
Obrigado!
(EDIT: By the way, eu sei que já existem pelo menos 3 perguntas "o que é uma mônada" no SO. No entanto, eu enfrento o mesmo problema com elas ... então essa pergunta é necessária imo, por causa do desenvolvedor do C # foco. Obrigado.)
Respostas:
A maior parte do que você faz na programação o dia inteiro está combinando algumas funções para criar funções maiores a partir delas. Normalmente, você tem não apenas funções na sua caixa de ferramentas, mas também outras coisas, como operadores, atribuições de variáveis e similares, mas geralmente o seu programa combina muitas "computações" para computações maiores que serão combinadas ainda mais.
Uma mônada é uma maneira de fazer isso "combinação de cálculos".
Normalmente, o seu "operador" mais básico para combinar dois cálculos é
;
:Quando você diz isso, você quer dizer "primeiro faça
a
, depois façab
". O resultadoa; b
é basicamente novamente uma computação que pode ser combinada com mais coisas. Esta é uma mônada simples, é uma maneira de combinar pequenos cálculos com outros maiores. O;
diz que "fazer a coisa à esquerda, em seguida, fazer a coisa à direita".Outra coisa que pode ser vista como uma mônada em linguagens orientadas a objetos é o
.
. Muitas vezes você encontra coisas assim:O
.
basicamente significa "avaliar o cálculo à esquerda e, em seguida, chamar o método à direita no resultado disso". É outra maneira de combinar funções / cálculos, um pouco mais complicado que;
. E o conceito de encadear as coisas.
é uma mônada, já que é uma maneira de combinar duas computações para uma nova computação.Outra mônada bastante comum, que não possui sintaxe especial, é esse padrão:
Um valor de retorno -1 indica falha, mas não há uma maneira real de abstrair essa verificação de erro, mesmo se você tiver muitas chamadas de API que precisam combinar dessa maneira. Isso é basicamente apenas outra mônada que combina as chamadas de função pela regra "se a função à esquerda retornou -1, retornamos -1 nós mesmos, caso contrário, chame a função à direita". Se tivéssemos um operador
>>=
que fizesse isso, poderíamos simplesmente escrever:Isso tornaria as coisas mais legíveis e ajudaria a abstrair nossa maneira especial de combinar funções, para que não precisemos nos repetir repetidamente.
E há muitas outras maneiras de combinar funções / cálculos que são úteis como padrão geral e podem ser abstraídas em uma mônada, permitindo que o usuário da mônada escreva códigos muito mais concisos e claros, já que toda a contabilidade e gerenciamento de as funções usadas são feitas na mônada.
Por exemplo, o acima
>>=
pode ser estendido para "fazer a verificação de erros e, em seguida, chamar o lado direito no soquete que recebemos como entrada", para que não precisemos especificar explicitamentesocket
muitas vezes:A definição formal é um pouco mais complicada, pois você precisa se preocupar em obter o resultado de uma função como entrada para a próxima, se essa função precisar dessa entrada e como você deseja garantir que as funções combinadas se encaixem. do jeito que você tenta combiná-los em sua mônada. Mas o conceito básico é que você formaliza maneiras diferentes de combinar funções.
fonte
;
exemplo: Quais objetos / tipos de dados são;
mapeados? (Pense emList
mapearT
paraList<T>
) Como;
mapear morfismos / funções entre objetos / tipos de dados? O que épure
,join
,bind
para;
?Faz um ano desde que publiquei esta pergunta. Depois de publicá-lo, mergulhei em Haskell por alguns meses. Gostei imensamente, mas coloquei-o de lado no momento em que estava pronto para me aprofundar nas mônadas. Voltei ao trabalho e foquei nas tecnologias que meu projeto exigia.
E ontem à noite, eu vim e reli essas respostas. Mais importante , reli o exemplo C # específico nos comentários de texto do vídeo de Brian Beckman que alguém menciona acima . Foi tão completamente claro e esclarecedor que decidi publicá-lo diretamente aqui.
Por causa desse comentário, não apenas sinto que entendo exatamente o que as mônadas são… Percebo que na verdade escrevi algumas coisas em c # que são mônadas… ou pelo menos muito próximas, e tentando resolver os mesmos problemas.
Então, aqui está o comentário - tudo isso é uma citação direta do comentário aqui por sylvan :
fonte
Uma mônada é essencialmente um processamento adiado. Se você está tentando escrever um código que tenha efeitos colaterais (por exemplo, E / S) em um idioma que não os permita, e apenas permita computação pura, um problema é dizer: "Ok, eu sei que você não fará efeitos colaterais. para mim, mas você pode calcular o que aconteceria se o fizesse? "
É meio que trapaça.
Agora, essa explicação o ajudará a entender a intenção geral das mônadas, mas o diabo está nos detalhes. Como exatamente é que você calcular as consequências? Às vezes, não é bonito.
A melhor maneira de fornecer uma visão geral de como alguém está acostumado à programação imperativa é dizer que isso o coloca em uma DSL, na qual operações que se parecem sintaticamente com as que você está acostumado fora da mônada são usadas para criar uma função que faria o que você deseja se puder (por exemplo) gravar em um arquivo de saída. Quase (mas não realmente) como se você estivesse construindo código em uma string para depois ser avaliado.
fonte
Maybe
eEither e
) e gerenciamento de estado (State s
,ST s
) me parecem instâncias específicas de "Por favor, calcule o que aconteceria se você tivesse [efeitos colaterais para mim]". Outro exemplo seria o não determinismo ([]
).Tenho certeza de que outros usuários postarão em profundidade, mas achei este vídeo útil até certo ponto, mas direi que ainda não estou no ponto de fluência com o conceito, para que eu pudesse (ou devesse) começar a resolver problemas intuitivamente com Mônadas.
fonte
Você pode pensar em uma mônada como um C #
interface
que as classes precisam implementar . Essa é uma resposta pragmática que ignora toda a matemática teórica da categoria por que você deseja optar por ter essas declarações em sua interface e ignora todos os motivos pelos quais deseja ter mônadas em um idioma que tenta evitar efeitos colaterais, mas achei um bom começo para alguém que entende interfaces (C #).fonte
Veja minha resposta para "O que é uma mônada?"
Começa com um exemplo motivador, funciona através do exemplo, deriva um exemplo de mônada e define formalmente "mônada".
Ele não assume conhecimento de programação funcional e usa pseudocódigo com
function(argument) := expression
sintaxe com as expressões mais simples possíveis.Este programa C # é uma implementação da mônada de pseudocódigo. (Para referência:
M
é o construtor de tipos,feed
é a operação "bind" ewrap
é a operação "return").fonte