Desculpe por mais uma pergunta sobre efeitos colaterais do FP +, mas não consegui encontrar uma que já respondesse isso.
Meu entendimento (limitado) da programação funcional é que os efeitos de estado / lado devem ser minimizados e mantidos separados da lógica sem estado.
Também recolho a abordagem de Haskell para isso, a mônada de E / S, conseguindo isso envolvendo ações com estado em um contêiner, para execução posterior, considerada fora do escopo do próprio programa.
Estou tentando entender esse padrão, mas, na verdade, para determinar se é necessário usá-lo em um projeto Python, então, quero evitar detalhes específicos do Haskell, se possível.
Exemplo bruto recebido.
Se meu programa converter um arquivo XML em um arquivo JSON:
def main():
xml_data = read_file('input.xml') # impure
json_data = convert(xml_data) # pure
write_file('output.json', json_data) # impure
A abordagem da mônada de E / S não é eficaz para fazer isso:
steps = list(
read_file,
convert,
write_file,
)
então se exime de responsabilidade, não chamando realmente essas etapas, mas deixando que o intérprete faça isso?
Ou, em outras palavras, é como escrever:
def main(): # pure
def inner(): # impure
xml_data = read_file('input.xml')
json_data = convert(xml_data)
write_file('output.json', json_data)
return inner
então, esperando que outra pessoa ligue inner()
e dizendo que seu trabalho está feito porque main()
é puro.
Todo o programa vai acabar contido na mônada IO, basicamente.
Quando o código é realmente executado , tudo depois de ler o arquivo depende do estado do arquivo, portanto ainda sofrerá os mesmos erros relacionados ao estado que a implementação imperativa, então você realmente ganhou alguma coisa, como programador que manterá isso?
Aprecio totalmente o benefício de reduzir e isolar o comportamento com estado, e é por isso que estruturei a versão imperativa assim: reunir entradas, fazer coisas puras, cuspir saídas. Esperemos que convert()
possa ser completamente puro e colher os benefícios da cachability, da segurança da linha, etc.
Aprecio também que os tipos monádicos podem ser úteis, especialmente em pipelines que operam em tipos comparáveis, mas não vejo por que as E / S devem usar mônadas, a menos que já estejam nesse pipeline.
Existe algum benefício adicional em lidar com os efeitos colaterais que o padrão de mônada de E / S traz, que estou perdendo?
main
em um programa Haskell é IO ()
- uma ação de E / S. Isso não é realmente uma função; é um valor . Todo o seu programa é um valor puro, contendo instruções que informam ao tempo de execução do idioma o que ele deve fazer. Todo o material impuro (realmente executando as ações de E / S) está fora do escopo do seu programa.
read_file
) e a usa como argumento para a próxima ( write_file
). Se você tivesse apenas uma sequência de ações independentes, não precisaria de uma mônada.