24 dias de Hackage, 2015 - dia 17 - ansi-wl-pprint: Evitando hackear com strings
por Franklin Chen
traduzido por Pedro Yamada
Esse é um artigo escrito por Franklin Chen e traduzido para o português. Ler original.
Encontro HaskellBR São Paulo
Índice de toda a série
O índice de toda a série está no topo do artigo para o dia 1.
Dia 17
Hoje, fazemos o inverso do que fizemos no day 14, que foi parsear de texto para uma árvore de sintaxe abstrata. Hoje nós fazemos o pretty-printing de uma árvore abstrata para texto.
Eu acho que no mundo mais amplo da programação, é muito comum ver soluções inflexíveis e ad-hoc para esse problema, usando string hacking e talvez, no melhor dos casos, templates (baseados em strings). Tipicamente, é difícil customizar estilos de indentação rápidamente, amarrar expressões e outras funcionalidades como uma solução ad-hoc.
Na comunidade de Haskell, uma solução melhor é mais comum, por causa do número de bibliotecas de qualidade para ajudar com pretty-printing.
ansi-wl-pprint
é uma dessas bibliotecas, que incluí não só muitos combinadores úteis, mas
também expõe suporte para output em cores, se você precisa disso (você não
precisa).
Update
Um comentário no Reddit notou que há outra versão da biblioteca de
pretty-printing,
annotated-wl-pprint
.
Isso parece ser muito legal, e há um
video por David Christiansen sobre seu uso com Idris.
De volta a nosso tipo de expressão de exemplo
Lembre que nosso tipo de expressão é:
Alguns exemplos de output pretty-printed
Vamos fazer pretty-print em uma expressão de exemplo. (Na vida real, nós criaríamos um corpo de expressões para pretty-print e as verificaríamos, e também escreveríamos testes do QuickCheck para confirmar várias propriedades.)
Para evitar o problema de construir um valor Exp
na mão, estamos reusando
nosso parser.
Um exercício para o leitor: escreva um gerador do QuickCheck de expressões
randômicas, e escreva um teste que verifica que quando você passa uma expressão
aleatória Exp
pelo pretty-printer e de volta pelo parser para uma Exp
,
você recebe o mesmo resultado!
O exemplo aqui formada somas separadas por espaços e produtos concatenados juntos, com parênteses mínimos e quebras de linha opcionais.
O código
O código é curto. A
documentação Haddock para o ansi-wl-pprint
é excelente, então você pode procurar nela para uma explicação dos combinadores
usados.
O conceito fundamental por trás da biblioteca é que há um tipo de dados Doc
que representa um “documento”, uma peça de informação pretty-printed, e que
há uma algebra combinando os documentos para os organizar de várias formas,
então você pode usar uma variedade de interpretadores sobre o documento para
realizar a conversão para string no final.
Exercício para o leitor: Há muitas formas de melhorar o pretty-printer, por exemplo alinhar os termos para ficar como:
Eu provavelmente primeiro transformaria uma Exp
em uma SugaredExp
que
representa a sintaxe abstrata intermediária dos termos e fatores, e então
escrever um pretty-printer sobre isso.
Duplicação de trabalho?
Você deve se perguntar sobre a duplicação de trabalho em escrever o parser e o pretty-printer. Não podemos escrever uma única especificação high-level para fazer ambos simultâneamente? Sim, há ferramentas para isso, mas estão fora do escopo desse artigo.
Conclusão
Pretty-printing é uma parte importante de uma interface baseada em texto,
seja para inspecionar código gerado ou criar boas mensagens de
erro. ansi-wl-pprint
é uma boa biblioteca para usar para pretty-printing>
Todo o código
Todo o código para a série estará nesse repositório do GitHub.
Nota do tradutor
Se você quer ajudar com esse tipo de coisa, agora é a hora. Entre no
Slack ou no
IRC da HaskellBR e
contribua. Esse blog e outros projetos associados estão na
organização haskellbr
no GitHub e em
haskellbr.com/git.