Quais problemas de programação as Mônadas solucionam? [fechadas]

14

Eu li muitos posts que explicam o que são mônadas, como unite bindfuncionam, algumas delas mergulhando diretamente na teoria das categorias tão abstratas (pelo menos para mim) que fazem os olhos sangrarem, outras ignorando isso completamente e tocando em analogias estranhas de burritos, caixas e o que não.

Depois de algumas semanas de estudo e muitos neurônios fritos, (eu acho), eu entendo como as mônadas funcionam. Mas ainda há uma coisa que escapa à minha compreensão, algo que poucas postagens realmente abordam (exceto IO e estado):

PORQUE?

Por que as mônadas são importantes? Por que eles são tão importantes? Quais são os problemas que eles estão resolvendo? Esses problemas só podem ser resolvidos com mônadas ou existem outras maneiras?

Dummy Me
fonte
3
Os programas são grandes e complexos. Precisamos de maneiras de estruturá-los. Existem muitos caminhos. Mônadas são uma. As setas são uma. Functors são um. Objetos, Classes, Funções, Métodos, Módulos, Traços, Mixins, Pacotes, são alguns outros. Realmente não está claro qual é a sua pergunta específica. Você está perguntando por que precisamos estruturar programas?
Jörg W Mittag
1
@ JörgWMittag: Eu não estou perguntando por que precisamos estruturar programas. Obviamente, um grande problema é dividido em outros menores que você pode resolver e depois combinar para obter a solução para o grande. Estou perguntando quais problemas o Monads resolve. É isso? Código de estruturação? É todo esse barulho? Por exemplo, em Haskell, é assim que você faz a E / S. Lá, a mônada é uma peça de teatro que age como algo puro quando na verdade não é. Minha pergunta está no título, não sei como afirmar isso de uma maneira mais clara.
Manequim Me
2
Por que mônadas?
Robert Harvey
1
@RobertHarvey: Eu também encontrei os dois primeiros links que você adicionou, mas, como nas respostas desses e de outros posts, as respostas vão diretamente para as mônadas Maybe, State e IO, saltando rapidamente para exemplos ou códigos e terminando com "há muito de problemas que podem ser resolvidos usando Mônadas ". Quais são os outros tipos de problemas? Estou procurando uma resposta de nível superior que, em vez de reiterar os mesmos exemplos, vá realmente à raiz dos problemas (sejam eles quais forem) e explique como as Mônadas os resolvem e por que é a melhor escolha, em vez de usar outra coisa. Muito obrigado pelo feedback.
Manequim Me

Respostas:

10

Você não precisa de mônadas para resolver nada. Eles apenas simplificam certas coisas. Muitas pessoas são abstratas e teóricas ao explicar mônadas. Principalmente, as mônadas são um padrão que surge repetidamente na programação. Ao reconhecer esse padrão, podemos simplificar nosso código e evitar reimplementar determinadas funções.

Para Haskell, de um ponto de vista concreto, a coisa mais visível que as mônadas permitem é a notação . A compreensão de listas em Haskell e em outros idiomas também tira grande vantagem das mônadas. Você também pode criar bibliotecas como Control.Monad .

Tudo isso fornece simplificações úteis e, depois de implementado para uma mônada, você o obtém automaticamente para todas as mônadas. Essa é uma das principais razões pelas quais a reutilização de código é muito mais fácil para a programação funcional do que outros paradigmas.

Karl Bielefeldt
fonte
2
Na verdade, eu diria que a coisa mais visível que as mônadas haskell permitem é uma maneira fácil de ter efeitos de IO que realmente funcionam da maneira que você espera. Acho que qualquer um que se pergunte o que as mônadas nos dão deve experimentar Miranda . Miranda é o idioma que o Haskell foi projetado para substituir e deve ser muito fácil de aprender para qualquer pessoa com experiência no Haskell. A principal diferença é que ele não possui E / S monádica, o que torna a linguagem muito mais difícil de trabalhar do que Haskell para qualquer projeto não trivial.
Jules
Sim, IOé a mônada mais proeminente de Haskell , mas eu não estava listando exemplos de mônadas individuais. Eu estava listando exemplos das abstrações abrangentes que eles permitem. Eu estava tentando entender por que, por exemplo, o primeiro cara a pensar em usar uma mônada para E / S consideraria uma boa ideia em geral.
Karl Bielefeldt
1
@Jules: Ou veja a história de Haskell. Antes das Mônadas, os designers da Haskell experimentavam Lazy Streams and Continuations como base para E / S, e ambos eram difíceis de usar.
Jörg W Mittag
5

É mais fácil entender se você olhar para as mônadas específicas e ver quais problemas elas resolvem. Por exemplo, em Haskell:

  • IO: Permite que o IO seja representado no sistema de tipos, para que você possa separar funções puras das funções que executam o IO.

  • Lista: permite fazer uma compreensão de lista e cálculos nodeterminísticos.

  • Talvez: Uma alternativa melhor para os nulos e suportando algo comparável ao operador de coalescência nula do C #.

  • Parsec: um DSL conveniente para escrever analisadores.

Portanto, é fácil (espero) ver a justificativa para as mônadas individuais, pois todas elas são bastante úteis. Mas os problemas que eles resolvem também são bem diferentes e, aparentemente, eles não têm muito em comum, exceto que todos estão relacionados a alguma lógica para operações de encadeamento. Mônadas são úteis porque permitem que você construa uma variedade de ferramentas.

Os exemplos acima podem ser implementados sem mônadas? Certamente eles poderiam ser implementados de maneira ad-hoc, mas ter mônadas incorporadas na linguagem permite o suporte direto ao idioma, como a donotação que funciona com todas as mônadas.

JacquesB
fonte
2

Uma coisa que torna confuso é que o "popular" funciona como binde <*>é orientado para a práxis. Mas, para entender os conceitos, é mais fácil observar outras funções primeiro. Também vale a pena notar que as mônadas se destacam porque são um pouco exageradas em comparação com outros conceitos conectados. Então, vou começar com functors.

Functors oferecem uma função (na notação Haskell) fmap :: (Functor f) => (a -> b) -> f a -> f b . Em outras palavras, você tem um contexto no fqual você pode elevar uma função. Como você pode imaginar, quase tudo é um functor. Lista, Talvez, Qualquer um, funções, E / S, tuplas, analisadores ... Cada um representa um contexto no qual um valor pode aparecer. Assim, você pode escrever funções extremamente versáteis que funcionam em praticamente qualquer contexto usando fmapou sua variante embutida <$>.

Que outras coisas você quer fazer com os contextos? Você pode combinar dois contextos. Então você pode querer obter uma generalização zip :: [a] -> [b] -> [(a,b)]por exemplo como este: pair :: (Monoidal f) => f a -> f b -> f (a,b).

Mas, como é ainda mais útil na prática, as bibliotecas Haskell oferecem Applicative, que é uma combinação de Functore Monoidal, e também deUnit , o que apenas acrescenta que você pode realmente colocar valores "dentro" do seu contexto unit.

Você pode escrever funções extremamente genéricas, declarando essas três coisas sobre o contexto em que está trabalhando.

Monadé apenas mais uma coisa que você pode afirmar além disso. O que eu não mencionei antes é que você já tem duas maneiras de combinar dois contextos: você pode não apenas paireles, mas também pode empilhá-los; por exemplo, você pode ter uma lista de listas. No contexto de E / S, um exemplo seria uma ação de E / S que pode ler outras ações de E / S de um arquivo, portanto você teria um tipo FilePath -> IO (IO a). Como podemos nos livrar desse empilhamento para obter uma função executável IO a? É aí que Monads joinchega, ele nos permite combinar dois contextos empilhados do mesmo tipo. O mesmo vale para analisadores, talvez etc. Ebind é apenas uma maneira mais prática de usarjoin

Portanto, um contexto monádico apenas oferece quatro coisas e pode ser usado com quase todo o maquinário desenvolvido para E / S, analisadores, falhas etc.

MarLinn
fonte
1

Mônadas permite que você expresse vários cálculos não puros, além de simplificar o código

  • computação stateful (obter / definir estado via mônada)
  • E / S (log, interface do usuário, arquivo ou apenas produzir / consumir uma lista de X)
  • Além disso, fluxo de controle "não linear" (ou seja, exceções, talvez etc.)

E, mais importante, sem comprometer as construções de linguagem pura e obter uma linguagem mais limpa com isso

Macke
fonte
2
É verdade - mas isso é apenas parte do uso das mônadas. Listar compreensões ou Maybenão estão relacionadas a nada externo.
JacquesB
Seria útil se os desobedientes explicassem por que o fizeram. Não vejo nada de errado com esta resposta.
Jules
@ JacquesB, no entanto, são stateful.
Jules
1
Tipos de Mundo, Tipos de Exclusividade, Tipos Lineares permitem que você faça isso também.
Jörg W Mittag 28/02
@Jules Listas como uma mônada não determinística é stateful? Você poderia esclarecer qual é a sua definição de "stateful"?
Jack