У меня есть некоторый опыт написания небольших инструментов на Haskell, и я нахожу его очень интуитивно понятным, особенно для написания фильтров (использующих interact
), которые обрабатывают их стандартный ввод и передают его на стандартный вывод.
Недавно я попытался использовать один такой фильтр для файла, который был примерно в 10 раз больше обычного, и я получил Stack space overflow
ошибку.
После некоторого чтения (например, здесь и здесь ) я определил два руководства по экономии места в стеке (опытные Хаскелеры, пожалуйста, исправьте меня, если я напишу что-то не то):
- Избегайте рекурсивных вызовов функций, которые не являются хвостово-рекурсивными (это справедливо для всех функциональных языков, которые поддерживают оптимизацию хвостовых вызовов).
- Введение
seq
для принудительной ранней оценки подвыражений, чтобы выражения не становились слишком большими, прежде чем их уменьшать (это характерно для Haskell или, по крайней мере, для языков, использующих ленивую оценку).
После введения пяти или шести seq
вызовов в моем коде мой инструмент снова работает гладко (также для больших данных). Тем не менее, я считаю, что оригинальный код был немного более читабельным.
Так как я не опытный программист на Haskell, я хотел спросить, является ли введение seq
таким способом обычной практикой, и как часто это можно увидеть seq
в рабочем коде Haskell. Или есть какие-то методы, которые позволяют избегать seq
слишком частого использования и при этом все еще использовать мало стекового пространства?