Tenho alguma experiência em escrever pequenas ferramentas em Haskell e acho muito intuitivo usar, especialmente para escrever filtros (usando interact) que processam sua entrada padrão e a canalizam para a saída padrão.
Recentemente, tentei usar um desses filtros em um arquivo que era cerca de 10 vezes maior que o normal e recebi um Stack space overflowerro.
Depois de fazer algumas leituras (por exemplo, aqui e aqui ), identifiquei duas diretrizes para economizar espaço na pilha (haskellers experientes, corrija-me se escrever algo que não esteja correto):
- Evite chamadas de função recursivas que não são recursivas de cauda (isso é válido para todos os idiomas funcionais que oferecem suporte à otimização de chamada de cauda).
- Introduzir
seqpara forçar a avaliação antecipada das subexpressões para que as expressões não cresçam muito antes de serem reduzidas (isso é específico para Haskell, ou pelo menos para idiomas usando avaliação lenta).
Depois de introduzir cinco ou seis seqchamadas no meu código, minha ferramenta roda sem problemas novamente (também nos dados maiores). No entanto, acho que o código original era um pouco mais legível.
Como não sou um programador experiente da Haskell, gostaria de perguntar se a introdução seqdessa maneira é uma prática comum e com que frequência a pessoa verá normalmente seqno código de produção da Haskell. Ou existem técnicas que permitem evitar o uso com seqmuita frequência e ainda usam pouco espaço na pilha?